java集合
一、集合基础
1、概述
2、ArrayList构造方法和添加方法
示例:
3、ArrayList的方法
二、集合进阶
三、Collection
1、概述
示例:
2、Collection集合常用方法
示例:
3、Collection遍历
4、List
(1)概述和特点
示例:
(2)List特有方法
(3)并发修改异常
示例:
(4)List迭代器
示例:
(5)增强for循环
示例:
不同方式循环遍历示例:
(6)List集合子类特点
代码示例:
(7)LinkedList特有功能
示例:
5、set
(1)概述
示例:
(2)哈希值
示例:
(3)HashSet概述和特点
示例:
(4)HashSet保证数据唯一性的源码分析
我们只要了解了 HashSet 执行添加元素的流程,就能知道为什么 HashSet 能保证元素不重复了?HashSet 添加元素的执行流程是:当把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他加入的对象的 hashcode 值作比较,如果没有相符的 hashcode,HashSet 会假设对象没有重复出现,会将对象插入到相应的位置中。但是如果发现有相同 hashcode 值的对象,这时会调用对象的 equals() 方法来检查对象是否真的相同,如果相同,则 HashSet 就不会让重复的对象加入到 HashSet 中,这样就保证了元素的不重复。
示例:
- 对于基本类型数据示例:
运行结果:
从上述结果可以看出,使用 HashSet 可以保证基础数据类型不重复。
- 对于自定义对象示例如下:
运行结果:
从上述结果可以看出,自定义对象类型确实没有被去重,那也就是说 HashSet 不能实现自定义对象类型的去重咯?其实并不是,HashSet 去重功能是依赖元素的 hashCode 和 equals 方法判断的,通过这两个方法返回的都是 true 那就是相同对象,否则就是不同对象,很明显两个new Person是不同对象,所以不属于重复对象。而前面的 Long类型元素之所以能实现去重,正是因为 Long类型中已经重写了 hashCode 和 equals 方法。
那么,想让 HashSet 支持自定义对象去重,只需要在自定义对象中重写 hashCode 和 equals 方法即可。ALT+INSERT,默认生成。
HashSet 底层是由 HashMap 实现的,它可以实现重复元素的去重功能,如果存储的是自定义对象必须重写 hashCode 和 equals 方法。HashSet 保证元素不重复是利用 HashMap 的 put 方法实现的,在存储之前先根据 key 的 hashCode 和 equals 判断是否已存在,如果存在就不在重复插入了,这样就保证了元素的不重复。
(5)LinkHashSet概述和特点
示例:
(6)TreeSet概述和特点
示例:
自然排序
①自然排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列
②如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现Comparable接口。
③实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过compareTo(Object obj) 方法的返回值来比较大小。
示例:
定制排序
①TreeSet的自然排序要求元素所属的类实现Comparable接口,如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要重写compare(T o1,T o2)方法。
②利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
③要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。
④此时,仍然只能向TreeSet中添加类型相同的对象。否则发ClassCastException异常。
⑤使用定制排序判断两个元素相等的标准是:通过Comparator比较两个元素返回了0。
示例:
四、Map
1、概述
示例:
2、map的功能
3、map的获取功能
示例:
4、map遍历的方式
(1)方式一
示例:
(2)方式二
示例:
5、案例解析
案例1:HashMap集合存储学生对象并遍历
案例2:ArrayList集合存储HashMap元素并遍历
案例3:HashMap集合存储ArrayList元素并遍历
案例4:统计字符串字符出现的次数
五、Collections
1、概述
示例:
2、案例
六、案例
1、斗地主需求分析
ArrayList实现
package com.itbianma_09; import java.util.ArrayList; import java.util.Collections; public class Demo { public static void main(String[] args) { //创建牌盒,用ArrayList集合实现 ArrayList<String> array = new ArrayList<>(); //往牌盒装牌 /* ♦,♥,♠,♣ 2.3.4...A 大王、小王 */ //定义花色数组 String[] colors = {"♦", "♥", "♠", "♣"}; //定义点数数组 String[] numbers = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A",}; for (String color : colors) { for (String number : numbers) { array.add(color + number); } } array.add("大王"); array.add("小王"); //洗牌,将牌打乱 Collections.shuffle(array); //发牌,遍历集合,给三个玩家发牌 ArrayList<String> firstArray = new ArrayList<>(); ArrayList<String> secondArray = new ArrayList<>(); ArrayList<String> thirdArray = new ArrayList<>(); ArrayList<String> dpArray = new ArrayList<>(); for (int i = 0; i < array.size(); i++) { String poker = array.get(i); if (i >= array.size() - 3) { dpArray.add(poker); } else if (i % 3 == 0) { firstArray.add(poker); } else if (i % 3 == 1) { secondArray.add(poker); } else if (i % 3 == 2) { thirdArray.add(poker); } } //看牌 lookPoke("第一个人",firstArray); lookPoke("第二个人",secondArray); lookPoke("第三个人",thirdArray); lookPoke("底牌",dpArray); } //看牌方法 public static void lookPoke(String name, ArrayList<String> array) { System.out.print(name + "的牌是:"); for (String poker : array) { System.out.print(poker + " "); } System.out.println(); } }
2、斗地主升级版
代码实现:
package com.itbianma11; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.TreeSet; public class Demo { public static void main(String[] args) { //定义HashMap,键是编号,值是牌 HashMap<Integer, String> hm = new HashMap<>(); //创建ArrayList,存储编号 ArrayList<Integer> array = new ArrayList<>(); //定义花色数组 String[] colors = {"♦", "♥", "♠", "♣"}; //定义点数数组 String[] numbers = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A",}; //装牌 int index = 0; for (String number : numbers) { for (String color : colors) { hm.put(index, color + number); array.add(index); index++; } } hm.put(index, "大王"); array.add(index); index++; hm.put(index, "小王"); array.add(index); //洗牌,洗的是编号 Collections.shuffle(array); //发牌,遍历集合,给三个玩家发牌 TreeSet<Integer> firstSet = new TreeSet<>(); TreeSet<Integer> secondSet = new TreeSet<>(); TreeSet<Integer> thirdSet = new TreeSet<>(); TreeSet<Integer> dptSet = new TreeSet<>(); for (int i = 0; i < array.size(); i++) { int x = array.get(i); if (i >= array.size() - 3) { dptSet.add(x); } else if (i % 3 == 0) { firstSet.add(x); } else if (i % 3 == 1) { secondSet.add(x); } else if (i % 3 == 2) { thirdSet.add(x); } } //看牌 lookPoke("第一个人", hm, firstSet); lookPoke("第二个人", hm, secondSet); lookPoke("第三个人", hm, thirdSet); lookPoke("底牌", hm, dptSet); } //看牌方法 public static void lookPoke(String name, HashMap<Integer, String> hm, TreeSet<Integer> set) { System.out.print(name + "的牌是:"); for (Integer index : set) { System.out.print(hm.get(index) + " "); } System.out.println(); } }