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也能确保插入顺序和遍历顺序一致

浙公网安备 33010602011771号