一、比较器排序
TreeSet是会对元素进行排序去重,有两种实现方案
1、 使用空参构造方法创建出的TreeSet,底层使用自然排序,即元素要实现Comparable接口才能实现排序
2、 可以使用有参构造,在创建TreeSet集合时,传入一个Comparator 比较器,这样存入的元素就会按照该比较器指定的排序方案排序( 不再使用默认的自然排序)
TreeSet(Comparator comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。
使用步骤
自定义类实现Comparator 接口
重写compar(T o1,T o2)方法
o1 就是之前compareTo方法中的this,即正在存储的元素
o2 就是之前compareTo方法中的o,即以前存储过的元素
方法返回值与之前compareTo方法的返回值一样
返回0 去重
返回负数放左边
返回正数放右边
在创建TreeSet时,创建该比较器对象,传入TreeSet的构造方法
二、Collections
类似于与Arrays,Collections是集合的工具类,方法都是静态的
Collections.reverse(List<?> list) 反转
Collections.shuffle(List<?> list) 混洗
Collections.sort(List<?> list) 排序
ArrayList<Integer> list = new ArrayList<>();
list.add(3);
list.add(2);
list.add(5);
list.add(4);
list.add(2);
list.add(1);
System.out.println(list);
// 排序 只能是升序
Collections.sort(list);
System.out.println(list);
// 反转
Collections.reverse(list);
System.out.println(list);
// 混洗
Collections.shuffle(list);
System.out.println(list);
结果:
[3, 2, 5, 4, 2, 1]
[1, 2, 2, 3, 4, 5]
[5, 4, 3, 2, 2, 1]
[2, 1, 2, 5, 3, 4]
三、Map<K,V>
Map代表双列集合,一次存储一对键值对(K,V)
Map是接口,代表是键映射到值的对象,一个Map不能包含重复的键,值允许重复.每个键最多只能映射到一个值,即可以通过键找到值,但是不能通过值找键.
方法都是非常常见的方法,但是Map是接口无法演示
Map有两个常用实现类
HashMap
TreeMap
四、HashMap[重点]
HashMap是Map的实现类,现在JDK8及以后底层是由数组+链表+红黑树实现并允许使用 null 值和 null 键
HashMap存储的元素是不保证迭代顺序,存储的键不允许重复,值允许重复
除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同
(HashMap允许使用null值和null键,Hashtable不允许)
补充: Hashtable是线程安全的map集合,效率低 ; HashMap是线程不安全的,效率高ConcurrentHashMap 即安全又高效的Map集合
HashMap的容量和扩容: 初始容量16,加载因子0.75 阈值是 16 * 0.75,达到阈值扩容至原来的2倍ps: 昨天学习的HashSet所有特性,其实就是HashMap的特性,包括去重原理
4.1 方法演示
构造方法
HashMap() 构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
HashMap(int initialCapacity) 构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
HashMap(int initialCapacity, float loadFactor) 构造一个带指定初始容量和加载因子的空 HashMap。
HashMap(Map<? extends K,? extends V> m) 构造一个映射关系与指定 Map 相同的新 HashMap。
方法
每个都很重要!!!!
// 创建空的HashMap;
HashMap<String,Integer> map = new HashMap<>();
System.out.println(map );
// 添加元素,一次添加一对,键值
// put方法的返回值,如果该键之前没有映射值,返回null
// 如果该键之前映射的有值,则将值覆盖,返回上次的旧值
Integer v1 = map.put("a",1);
System.out.println(v1 );
Integer v2 = map.put("a", 2);
System.out.println(v2 );
Integer v3 = map.put("d", 4);
System.out.println(v3 );
map.put("b",2);
System.out.println(map );
// 取出元素
// 通过键返回值
Integer v = map.get("a");
System.out.println(v );
// 集合大小(元素个数)
System.out.println(map.size() );
// 集合是否为空
System.out.println(map.isEmpty() );
// 清空集合
//map.clear();
// 集合大小(元素个数)
//System.out.println(map.size() );
// 集合是否为空
//System.out.println(map.isEmpty() );
// 移除元素,根据键移除整个键值对,返回值
Integer a = map.remove("a");
System.out.println(a );
System.out.println(map );
/**
* boolean containsKey(Object key)
* 判断集合中是否包含指定键,有则返回 true。
* boolean containsValue(Object value)
* 判断集合中是否包含指定值,有则返回 true。
*/
System.out.println(map.containsKey("A"));
System.out.println(map.containsValue(11));
4.2 迭代/遍历
Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容
1 、 Set<Key> keySet() 键集,返回一个Set集合,其中只有键
2、 Collection<Value> values() 值集,返回一个Collection集合,其中只有值
3、 Set<Map.Entry<K,V>> entrySet() 键值映射集,返回一个Set集合,其中放着key-value对象
4.2.1 键集
HashMap<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
map.put("d", 4);
System.out.println(map);
// 键集遍历
Set<String> keySet = map.keySet();
// 获得迭代器
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("---------");
for (String key : keySet) {
System.out.println(key);
}
4.2.2 值集
// 值集
Collection<Integer> value = map.values();
Iterator<Integer> iterator = value.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("---------");
for (Integer integer : value) {
System.out.println(integer);
}
4.2.3 键值映射集 [非常重要]
Entry是Map接口中的内部接口,代表是一个键值对,即包含键和值.且该Entry接口中提供了关于操作单个键,值的方法
K getKey()
V getValue()
// 键值映射集
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
Iterator<Map.Entry<String,Integer>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Map.Entry<String,Integer> entry = iterator.next();
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + "-->" + value);
}
System.out.println("----=====");
for (Map.Entry<String, Integer> entry : entrySet) {
System.out.println(entry);
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
4.3 去重原理
HashMap的去重其实就是HashSet的去重,因为HashSet底层就是HashMap
1、在创建HashSet时,其实在底层创建了HashMap

2、在向set中添加元素时,其实是向map的key上添加

所以HashMap的键的去重原理就是
向键存储数据时,先调用键的hashcode()方法
如果hashcode值不一样则直接存储
如果hashcode值一样,再调用元素的equals()方法
如果equals方法返回false,则存储
如果equals方法返回true,则不存储
4.4 HashMap的应用
场景一: 适合有关联映射的场景
设计方法,传入字符串,输出该字符串中每个字符出现的次数,使用HashMap实现例如: “abcHelloabcWorld”,输出 a出现2次,b出现2次,,,l出现3次,H出现1次
HashMap<String, Integer> map = new HashMap<>();
Scanner scanner = new Scanner(System.in);
String str = scanner.next();
// char[] chars = str.toCharArray(); 也可转为字符数组
String[] strArr = str.split("");
for (int i = 0; i < strArr.length; i++) {
String s =strArr[i];
if(!map.containsKey(s)){
map.put(strArr[i], 1);
}else {
Integer count = map.get(s);
map.put(strArr[i],++count);
}
}
System.out.println(map);
Set<Map.Entry<String,Integer>> set = map.entrySet();
Iterator<Map.Entry<String,Integer>> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
场景二: Map可以当实体类对象
public class Student{
private int age;
private String name;
// ...
}
Student s1 = new Student(18,"zs");
s1.getAge();
s1.getName();
使用Map模拟对象
HashMap<String, Object> stu = new HashMap<>( );
stu.put("age",18);
stu.put("name","zs");
stu.put("sex","男");
五、TreeMap
TreeMap底层是红黑树(平衡二叉树的一种)同样式存储键值对,键不允许重复且还会排序默认是根据键元素的自然顺序排序或者,根据创建TreeMap时指定的Comparator比较器来排序
5.1 方法演示
TreeMap<String, Integer> map = new TreeMap<>( );
map.put("b",2);
map.put("e",5);
map.put("a",1);
map.put("a",2);
map.put("d",4);
map.put("c",3);
// 其他正常的map方法...
// 三个遍历方法...
// 特殊的,有关于头尾操作的方法
// 获得排序后的第一个
String key = map.firstKey( );
// 获得排序后的第一个Entry
Map.Entry<String, Integer> entry = map.firstEntry( );
System.out.println(entry );
5.2 TreeMap排序去重原理
昨天学习的TreeSet的底层其实就是TreeMap
创建TreeSet时,创建TreeMap

向set集合添加元素时,其实是向TreeMap的键添加元素

即TreeMap的排序去重原理是什么?其实如果自然排序就是compareTo(),如果是比较器排序就是compar()方法
方法返回0 去重
方法返回负数 放在树左侧
方法返回正数 放在树的右侧
六、总结
集合体系中最重要最常见的两个集合是ArrayList,HashMap
其他的,
记住常用的API(crud和遍历)
记住List和Set区别
记住ArrayList和LinkedList区别
记住HashMap扩容,去重原理
记住TreeMap的排序去重原理