Set和比较器和List
- set特点:无序 不可重复,添加循序和取出循序不一定一致
- Set ——>SortedSet——>TreeSet:底层是红黑树,要添加的元素必须按照某个规则进行排序
- 数字默认升序,字符串 默认比较每一位的ASCII码值,时间 默认自然日期(昨,今,明,后)
***`public static void main(String[] args) throws ParseException {
TreeSet treeSet = new TreeSet();
//数字按照升序排序
treeSet.add(3);
treeSet.add(2);
treeSet.add(1);
System.out.println(treeSet);
//字符串按照ASCII升序排序
//每位比较,相同则比较后面一位
//1和12的1比,然后12的2和1的第二位比,没有则12大
//1,10,12,2
treeSet = new TreeSet();
treeSet.add("1");//49
treeSet.add("12");
treeSet.add("11");
treeSet.add("2");
System.out.println(treeSet);
//时间 自然日期
String strTime1 = "2021-07-15";
String strTime2 = "2021-07-13";
String strTime3 = "2020-08-15";
String strTime4 = "2022-02-11";
treeSet = new TreeSet();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d1 = sdf.parse(strTime1);
Date d2 = sdf.parse(strTime2);
Date d3 = sdf.parse(strTime3);
Date d4 = sdf.parse(strTime4);
treeSet.add(strTime1);
treeSet.add(strTime2);
treeSet.add(strTime3);
treeSet.add(strTime4);
System.out.println(treeSet);
}`
-
比较器
-
比较器类 有两种-1 java.lang.Comparable 接口 并实现 compareTo方法
-
2 java.util.Comparator 比较器类
-
为什么 String ,Integer ,Data能排序?其他类型行不
因为他们三个类都实现了Comparable接口 并实现了compareTo()方法而 往treeSet中添加数据的时候,会自动调用该对象的 compareTo方法,因此,他们可以排序但是如果我们想添加其他元素,尤其是自定义类型的时候,就不行了,需要实现Comparable接口,并实现了compareTo()方法 -
比如我们现在要保存 数字,并且是降序排序
-
而Integer 中默认是升序,我们没有办法更改他的源码,所以可以使用Comparator解决该问题
-
通过treeMap源码发现,Comparator优先级大于Comparable
-
所以我们可以利用Comparator的优先级,来自定义排序规则
-
我们自定义类型 需要排序,优先使用Comparable来实现,这样 如果不能满足别人的需求,还可以通过comparator对排序进行扩展
-
我们操作的是别人定义的类型的话,都需要使用comparator进行扩展,因为你改不了人家的源码
1 . 本来有排序,比如Integer,默认升序,但是不能满足我们的排序需求,此时需要使用comparator进行扩展
2 .不支持排序,也就是说该类型没有实现comparable接口,不能排序,但是我们需要排序,也可以通过comparator进行扩展
3 .总之 其他类型.无法满足我们的排序规则的时候,都可以使用comparator进行扩展排序
/**
* list想要排序,元素必须实现comparable接口
*
* 如果元素自身没有实现comparable接口,是不能调用sort方法,会报错
*
* 但是 想要比较也可以,不管他是否实现comparable接口,或者是排序规则不是我们想要的
*
* 都可以使用comparator进行比较,sort方法有一个重载,接收comparator
*/
public class Collection_04_ListSort_01 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add(2);
arrayList.add(21);
arrayList.add(12);
arrayList.add(4);
Collections.sort(arrayList);
System.out.println(arrayList);
Collections.sort(arrayList, new Comparator() {
public int compare(Object o1, Object o2) {
//o1是要添加的元素,o2是集合中的元素
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2 - i1;
}
});
System.out.println(arrayList);
}
}
- 散列表:数组中保存的链表
- HashSet 底层就是HashMap 的key部分,屏蔽了HashMap的valu
- 而HashMap底层是散列表
- 添加过程:
-
1 根据key生成hash值(hashCode方法)
-
2 根据生成hash值,通过hash算法得到数组下标 i=(n-1)&hash
-
3 调用key的equals方法,和数组中对应的链表的每一个节点进行比较
-
4 如果不存在,就添加进去,如果存在,就不添加
-
5 java8开始,引入了红黑树,如果链表个数 大于等于9 就把链表转型为红黑树 从而加快查询效率