Day20 比较器,set,map,散列
- Set和排序
1.1概述
set特点:无序,不可重复,添加顺序和取出顺序不一定一致
Set->SortedSet->TreeSet:底层是红黑树,要添加的元素必须按照某个规则进行排序
1.2TreeSet
1.2.1概述
set特点:无序,不可重复,添加顺序和取出顺序不一定一致
Set->SortedSet->TreeSet:底层是红黑树,要添加的元素必须按照某个规则进行排序
数字默认升序,字符串默认比较每一位的ASCLL码,时间默认自然日期(昨天,今天,明天,后天...)
1.2.3为什么会排列?其他类型行不行?
为什么String ,Integer,Date能排序,其他类型行不行
因为他们三个都实现了Comparable接口 并实现了compareTo()方法
而往treeSet中添加教程数据的时候,会自动调动该对象的compareTo方法,因此,他们可以排序
但是如果我们想添加其他元素,尤其是自定义类型的时候,就不行了,需要实现CompareTo()方法
1.3排序
1.3.1
比较器类 有两种
1 java。lang.Comparable 接口 并实现 compareTo方法
2 java.util.Comparator 比较器类
为什么String ,Integer,Date能排序,其他类型行不行
因为他们三个都实现了Comparable接口 并实现了compareTo()方法
而往treeSet中添加教程数据的时候,会自动调动该对象的compareTo方法,因此,他们可以排序
但是如果我们想添加其他元素,尤其是自定义类型的时候,就不行了,需要实现CompareTo()方法
1.3.2 Comparable
如果我们的自定义类型想要放到treeSet中必须实现Comparable接口,否则就无法使用treeSet进行数据保存
2.public int compare(Object o){}
this是要添加的元素,o是集合中的每一个元素
返回值为0,说明相等,就不添加
返回值小于0,说明要添加的元素比集合中的元素小,就放到前面
返回大于0,说明要添加的元素比集合的元素大,就放到后面
Comparator
1.3.3.1概述
比如我们现在要保存数字,并且是降序排序
而Interger 中默任是升序,我们没有办法更改源码,所以可以使用Comparator解决该问题
通过treeMap源码发现Comparator优先级 大于Comparable
1.3.1Collection
list想要排序,元素必须实现comparable接口
如果元素自身没有实现comparaable接口,是不能调用sort方法的,会报错
但是想要比较也可以,不管他是否实现comparable接口,或者是排序规则不是我们想要的
都可以使用comparator进行比较,那么sort方法有一个重载接收comparator
总结
如果添加的元素是我们写的,那么我们应该使用comparable进行排序,因为对扩展开放,当满足不了别人的需求的时候,人家还可以使用comparator进行扩展
如果添加的元素不是我们写的,是别人写的,那么我们肯定不能更改人家的源码
此时我们可以通过comparator和comparable进行重新排序
因为comparator和comparable同时存在的时候,comparator优先级要高
1.4HashSet
1树
1.1二叉查找树
类似于二分法,查找效率高
左叶子:用于小于根节点的值
右叶子:用于大于根节点的值
这种方式是二查找的思想,查询所需要的最大次数,就等同于二叉树的高度
在添加数据的时候,也是类似的的
数据太靠一边的话,虽然符合二查找树的特性,但是性能大大折扣,几乎变成线性的
1.2红黑树
为了解决二查找树多次插入新节点而找到的不平衡,红黑树就诞生了
1.2.1节点是红的或者黑的
- 每个根节点是黑的
左旋转:让根结点被右节点取代自己成为左节点
右旋转:让根结点被左节点取代自己成为右节点
右边黑色数量多,就左旋转
左边黑色数量多,就右旋转
散列表
数组中保存的链表
- 哈希表
HashSet底层就是HashMap的key部分,屏蔽了HashMap的value
而HashMap底层就是散列表
添加过程:
- 根据key生成hash值(hashCode方法)
- 根据生成hash值,通过hash算法得到数组的下标
- 调用key的equals方法和数组中对应的链表的每一个节点进行比较
- 如果不存在,就添加进去,如果存在,就不添加
- Jaiva8开始,引入红黑树,如果链表个数大于等于9就把链表转型为红黑树从而加快查询效率
覆写equal的时候还需要考虑hashCode因为需要使用hashCode和equals共同表示对象的唯一性
- 调用key的hashCode方法生成hash值,所以记得重写
- 生成数组索引
- 判断数组对应的索引是否右节点
- 没有节点 直接添加
- 有节点 判断是否存在当前元素
- 如果链表中节点个数大于等于8就转为树