Set

一 HashSet

HashSet实现了Set接口,实际上是HashMap,HashMap底层是(数组+链表+红黑树)

可以存放null值,但只能有一个null

HashSet不保证元素是有序的,取决于hash后,在确定索引的结果(即,不保证存放元素的顺序和取出顺序一致)

不能有重复元素/对象

 

说明:

1 HashSet底层是HashMap

2 添加一个元素时,先得到hash值,转成索引值

3 找到存储数据表table,看这个索引位置是否已经存放的有元素

4 如果没有,直接加入

5 如果有,调用equals比较,如果相同,就放弃添加,如果不相同,则添加到最后

6 在java8中,如果一条链表的元素个数达到TREEIFY_THRESHOLD(默认8),并且table的大小>=MIN_TREEIFY_CAPACITY(默认64)就会进行树化(红黑树)

 

HashSet的扩容和转成红黑树机制

1 HashSet底层是HashMap,第一次添加时,table数组扩容到16,临界值(threshold)是16*加载因子(loadFactor)0.75=12

2 如果table数组使用到了临界值12,就会扩容到16*2=32,新的临界值就是32*0.75=24,依次类推

3 在java8中,如果一条链表的元素个数达到TREEIFY_THRESHOLD(默认8),并且table的大小>=MIN_TREEIFY_CAPACITY(默认64)就会进行树化(红黑树),否则仍然采用数组扩容机制

 

二 LinkedHashSet

LinkedHashSet是HashSet的子类

LinkedHashSet底层是一个LinkedHashMap,底层维护了一个 数组+双向链表

LinkedHashSet根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的

LinkedHashSet不允许添加重复元素

 

说明:

1 在LinkedHashSet中维护一个 hash表和双向链表(LinkedHashSet有head和tail)

2 每一个节点有pre和next属性,这样可以形成双向链表

3 在添加一个元素时,先求hash值,在求索引,确定该元素按在hashtable的位置,然后将添加的元素加入到双向链表(如果已经存在,不添加,原则和hashset一样)

4 这样的话,遍历LinkedHashSet也能确保插入顺序和遍历顺序一致

posted @ 2021-06-28 17:47  chentaohere  阅读(153)  评论(0)    收藏  举报