HashSet和LinkedHashSet

216 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。 ​

image.png

特点

  • 实现了set接口,底层是HashMap,HashMap线程不安全,其无参构造方法如下 public HashSet() { map = new HashMap<>(); }

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

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

  • 不能有重复元素

  • 底层是数组+链表+红黑树

  • 调用无参构造,初始容量为16

插入细节

  • 添加一个元素,先得到hash值,再转成索引值
  • 找到存储数据表table,看这个索引位置是否已经存放的有元素,如果没有,直接加入,如果有就调用equals比较,如果相同就放弃添加,否则添加到最后,【HashMap 比较key是否相同,相同就直接替换】
  • 一条链表的元素个数达到默认值(8),并且table的大小大于默认值(64),此链表就会进行树化(红黑树),table的大小就行hashSet中所有元素的个数
  • 【HashMap 底层维护了Node类型的数组table,默认为null】
  • 当创建对象时,将加载因子初始化为0.75
  • 第一次添加,需要扩容table容量为16,临界值为12,以后再次扩容,则需要扩容table容量为原来的2倍

image.png

  • 是HashSet的子类,扩容机制一样,因子也是0.75
  • 底层维护的是LinkedHashMap  即是数组table+双向链表+红黑树,维护有个head头节点和tail尾节点
  • 加入顺序和取出顺序是一致 子类扩展的操作针对于HashSet
  • 第一次添加时候,直接将table数组扩容到16
  • 数组类型是HashMapNode[],存放的节点类型是LinkedHashMapNode[] ,存放的节点类型是LinkedHashMapEntry,每个节点有个before和after属性,指向前节点和后节点