[2025.1.11 JavaSE学习]集合-4(Set接口 && HashSet && LinkedHashSet)

Set接口方法

  • 无序,添加和取出顺序不一样,无索引
  • 没有重复的元素,最多包含一个null
  • Set接口也是Collection子接口,常用方法一样
  • Set同Collection遍历方式一样:
    • 可以使用迭代器(Iterator it = set.iterator())
    • 可以使用增强for
    • 不能使用索引方式

HashSet

  • HashSet实现了Set接口
  • HashSet实际上底层为HashMap,其构造方法如下:
public HashSet(){
	map = new HashMao<>();
}
  • 可以存放null值,但是只能有一个
  • HashSet不保证元素是有序的,取决于hash后,再确定索引的结果
  • 不能有重复元素
  • 底层为数组+链表+红黑树

HashSet扩容机制

  • 添加一个元素时,先得到其hash值(hashCode()),会转换为索引值

  • 找到table中索引位置是否存放有元素

  • 如果没有,直接加入

  • 如果有,调用equals()进行比较(底层为地址比较,String内部重写了equals方法,会根据字符串内容进行比较

  • equals比较后,如果相同,就放弃添加,如果不相同,则添加到最后

  • 在jdk8中,如果一个索引链表的元素个数到达TREE_THRESHOLD(默认为8)table使用大小大于等于MIN_TREEIFY_CAPACITY(默认64),就会红黑树化

    • 每次将元素添加在链表后,立刻判断是否已经达到8个节点,如果是,则调用treeifyBin()
    • 在转为红黑树之前,需要进行判断条件:
      if(tab == null || (n = tab.length) < (MIN_TREEIFY_CAPACITY(64))) resize();
    • 如果上面条件成立,先对table进行扩容;否则进行红黑树化
  • 一些细节:

    • 第一次添加时,table数组就扩容到16,临界值threshold为16loadFactor(160.75=12)
    • 如果table数组使用达到了临界值12,就会扩容到16*2=32,新的临界值就是32*0.75=24,以此类推
    • 若达到上述条件,则红黑树化
    • PS:table使用大小算的是add()方法的成功次数,即单索引上的链表+1也算在内
    • 重写 equals 方法时,必须同时重写 hashCode 方法:
    @Override
    public boolean equals(Object o){
    	if(this == o) return ture;//判断是否为自身
    	if(o == null || getClass() != o.getClass())return false;//判断是否为空,或者不同类
    	Employee employee = (Employee)o;
    	return age == employee.age && Objects.equals(name, employee.name);
    }
    
    @Override
    public int hashCode(){//为了根据属性生成相同的hashCode
    	return Objects.hash(name, age);
    }
    

LinkedHashSet

  • 继承了HashSet
  • 底层为一个LinkedHashMap,底层维护了数组+双向链表
  • 根据元素的hashCode值决定存储位置,同时使用链表维护元素的次序,使得元素看起来是以插入顺序保存的
  • 不允许添加重复元素
  • 工作逻辑,按插入顺序建立双向链表,而决定插不插入的逻辑则和HashSet一样
  • 源码分析:
    • 添加第一次时,直接将数组table扩容到16
    • 数组为HashMap$Node(为LinkedHashMap父类,数组多态),存放的元素为LinkedHashMap$Entry类型($是外部类内部类分隔符),Entry为LinkedHashMap内部静态类,继承了HashMap.Node
posted @   Luna-Evelyn  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示