Set系列的公共特点:无重复、无索引,不可用普通for循环,API和Collection重复
HashSet:采取哈希表存取数据
哈希表组成?
JDk8之前:数组+链表, JDK8以后:数组+链表+红黑树
哈希值?
利用HashCode方法计算出来的对象的int表达形式,哈希值的作用是,根据对象的哈希值计算出在数组中的存放的索引位置,如下图公式,这样存取都很快,hashCode默认是通过对象内存地址映射过来的
利用哈希值计算在数组中的位置?
哈希值的特点?
何时以及为什么要重写hashcode和equals方法?
当对象是String,Integer时不需要重写,源码已经重写了;
当集合中存储的对象为自定义对象,必须重写hashCode和equals方法!!!
因为hashCode默认是通过对象内存地址映射过来的,我们想要用属性值来计算哈希值,所以重写
因为equals默认比较的是地址值,我们想要比较的是内部属性值,同时,重写equals也是防止哈希冲突造来的影响,所以重写。
HashSet添加元素过程在JDK8以前的底层原理?
1、首先自动创建一个默认长度16,默认加载因子为0.75(扩容时机)的数组table
2、调用hashcode方法,根据元素的哈希值和数组长度计算出要存入的位置
3、判断当前位置是否为null如果空,直接存入
4、如果非空,调用equals方法比较属性值
5、一样的话不存,不一样的话代替老元素存入数组位置,并将老元素挂在新元素下面,形成链表
HashSet添加元素过程在JDK8以后的底层原理?
1,2,3,4和JDK8以前一样
5、一样的话不存,不一样的话老元素不动,并将新元素挂在老元素下面,形成链表
扩容时机?
元素会越存越多,当存入16*0.75=12个元素时,数组会扩容到原先2倍,16——32.
在JDK8以后:链表长度超过8,且数组长度大于等于64时,自动转为红黑树
在JDK8以后,数组+链表+红黑树。
HashSet的几个问题?
1、HashSet存和取顺序为何不同?
存入位置是靠哈希值确定的,所以存入的顺序和元素在数组中的顺序无关;在取的时候,从默认数组table的0索引位进行遍历,但是,这个遍历位置和存入顺序无关,无法确定他是否是第一个存入的。
2、HashSet为什么没有索引?
因为在哈希表中可能存在链表,数组的一个索引只能代表一条链表,而链表上存在许多元素,无法表示出来这些元素的索引。因为底层的结构不唯一,结构太多导致于确定索引比较困难,所以舍弃了索引机制
3、HashSet利用什么保证数据去重?
利用Hashcode得到哈希值,获取元素在数组中的位置;然后利用equals比较对象属性值是否相同
4、HashSet的底层数据结构?
JDk8之前:数组+链表, JDK8以后:数组+链表+红黑树
5、HashSet好处
用Hashset写数据校验很方便,通过add的返回值判断数据有无重复然后返回不同的提示
LinkedHashset:有序——存入和取出顺序相同
利用双向链表记录存储顺序,从而达到有序
如果要用数据去重,用HashSet还是LinkedHashSet?
因为linkedHashset在Hashset基础上多做了事情,效率较低
TreeSet:可排序
1、什么是可排序?
可以按照元素的默认规则(由小到大)进行排序
2、默认排序规则是什么?(数值)
遇到字符串组合情况,一位一位的对应比较ASCII码表:
3、TreeSet集合底层数据结构是什么?
基于红黑树的数据结构实现排序的,增删改查性能都较好
4、除了普通for遍历不可以使用,其他均可以遍历
5、非默认的排序规则(2种):存储的对象为自定义对象时
第一种:重写Comparable接口中的抽象方法(默认)
例子:创建自定义学生对象,并按照年龄大小排序
在不进行任何操作下,直接add学生对象:系统报错,因为无法按照规则排序
进行重写方法:
重写Comparable接口中的抽象方法的具体原理:o表示已有的数据,this为插入数据
按照add的顺序,构造红黑树,按照红黑树的红黑规则:
看看TreeSet如何进行的排序:
对重写Comparable接口中的抽象方法进行打印this和o:
结果:
add的顺序:
可以看出o就是红黑树原来存储的元素,this为新添加的元素,添加过程按照红黑树的红黑规则
第二种:创建TreeSet对象时,传递比较器Comparator指定规则
格式?
何时使用?
在第一种方法不满足要求后使用,比如字符串String已经默认重写了Compareto方法,如果我们不想按照默认方法,但又不方便修改源码,则需要利用这种方法来重新定义排序规则,两种方法同时存在时,听比较器Comparator的指定规则。
例题1:TreeSet对象排序,string数据类型,按长度排序(非默认)
如果要降序排列:return -i;