当前位置: 首页 > article >正文

HashSet经典面试题

基本特点

  • 唯一性HashSet 中的元素不能重复,这是通过 HashMap 的键(key)的唯一性实现的。

  • 无序性HashSet 不保证元素的存储顺序,因为它的底层是基于哈希表的。

  • 线程不安全HashSet 是非线程安全的,若需要线程安全版本,可以使用 Collections.synchronizedSet()ConcurrentHashMap 相关实现。

前置知识:

public class test01 {
    public static void main(String[] args) {

        HashSet<Student> set = new  HashSet<>();
        Student stu_1 = new Student("张三", 18);
        set.add(stu_1);

        Student stu_2 = new Student("张三", 18);
        set.add(stu_2);
        
        Iterator<Student> it = set.iterator();
        while(it.hasNext()) {
            System.out.println(it.next().toString());
        }
    }
}

 根据hashset无序不重复的特性,即使引用地址不同,仍然能够控制元素不重复。

问题1:

下面的remove是否能够成功移除stu_1对象?

public class test01 {
    public static void main(String[] args) {

        HashSet<Student> set = new  HashSet<>();
        Student stu_1 = new Student("张三", 18);
        set.add(stu_1);
        stu_1.setName("李四");
        set.remove(stu_1);   //执行一次删除

        Iterator<Student> it = set.iterator();
        while(it.hasNext()) {
            System.out.println(it.next().toString());
        }
    }
}

移除操作的核心在于,存储在HashSet 中的对象是否正确重写 hashCode() 方法。

 代码执行结果显示,stu_1对象并没有被删除,remove操作失败:

代码运行的逻辑

1. HashSet 添加元素
  • 当你调用 set.add(stu_1) 时,HashSet 会根据 stu_1hashCode() 计算出一个哈希值,找到对应的桶(bucket),并将元素添加到该位置。
  • 如果没有自定义 hashCode 方法,stu_1 的哈希值来自 Object 类的 hashCode() 方法,默认基于对象内存地址生成。
2. 修改对象后
  • 调用了 stu_1.setName("李四")修改了对象的状态。如果 hashCode() 是基于对象的属性(如 nameage)计算的,那么 hashCode 的值就会发生变化。
  • HashSet 中的哈希表是静态的,修改对象不会触发重新计算哈希值,因此哈希表的结构没有变化。此时,HashSet 的数据结构已经失效,stu_1HashSet 中变成了“找不到”的元素。
3. 调用 remove 方法
  • 当你调用 set.remove(stu_1) 时,HashSet 会用当前 stu_1hashCode 值去哈希表中寻找对应的桶。
  • 因为 stu_1hashCode 已经改变,HashSet 找不到之前存储的位置,所以删除失败。

问题2:

重写hashcode()方法的前提下,stu_2能否添加进hashset集合中?

public class test01 {
    public static void main(String[] args) {

        HashSet<Student> set = new  HashSet<>();
        Student stu_1 = new Student("张三", 18);
        set.add(stu_1);
        stu_1.setName("李四");
        set.remove(stu_1);
        //新增代码是否生效?
        Student stu_2 = new Student("李四", 18);
        set.add(stu_2);

        Iterator<Student> it = set.iterator();
        while(it.hasNext()) {
            System.out.println(it.next().toString());
        }
    }
}

        可以添加成功,因为第一次set.add(stu_1) 时,HashSet 会根据 stu_1 的“张三”和18来计算哈希值,而这一次添加对象,却是根据李四和18计算出来的。

问题3:

stu_3能否添加成功?

public class test01 {
    public static void main(String[] args) {

        HashSet<Student> set = new  HashSet<>();
        Student stu_1 = new Student("张三", 18);
        set.add(stu_1);
        stu_1.setName("李四");
        set.remove(stu_1);

        Student stu_2 = new Student("李四", 18);
        set.add(stu_2);
        //新增代码是否生效?
        Student stu_3 = new Student("张三", 18);
        set.add(stu_3);
        
        Iterator<Student> it = set.iterator();
        while(it.hasNext()) {
            System.out.println(it.next().toString());
        }
    }
}

 虽然hashcode得到的哈希码是一样的值,找到的桶是一样的,但是equals方法结果为false,因此哈希碰撞的结果是添加进单链的后面。


http://www.kler.cn/a/517785.html

相关文章:

  • Java Web-Tomcat Servlet
  • 自签证书的dockerfile中from命令无法拉取镜像而docker的pull命令能拉取镜像
  • 【Uniapp-Vue3】setTabBar设置TabBar和下拉刷新API
  • 【25美赛A题-F题全题目解析】2025年美国大学生数学建模竞赛(MCM/ICM)解题思路|完整代码论文集合
  • 奖励模型:解析大语言模型的关键工具
  • Next.js 实战 (十):中间件的魅力,打造更快更安全的应用
  • Git知识分享
  • 5. 马科维茨资产组合模型+政策意图AI金融智能体(Qwen-Max)增强方案(理论+Python实战)
  • 企业微信第三方应用开发006_开发配置_配置网络穿透_配置数据回调_指令回调_连接后台---企业微信开发009
  • ffmpeg的AVOption用法
  • YOLOv5模型版本详解:n/s/m/l的区别与选型指南
  • GEE | ERA5不同土壤层水分和温度变化
  • 【gopher的java学习笔记】一文讲懂controller,service,mapper,entity是什么
  • ChatGPT大模型极简应用开发-CH5-使用 LangChain 框架和插件增强 LLM 的功能
  • pip国内源汇总
  • mysql-06.JDBC
  • 财税资金数据管理一体化大屏 | 智慧金融合集
  • YOLOv11实战天气图像识别
  • openstack单机安装
  • 激光线扫相机无2D图像的标定方案
  • Level2逐笔成交逐笔委托毫秒记录:今日分享优质股票数据20250124
  • 朴素贝叶斯(Naive Bayes)详解
  • 寒假刷题Day13
  • UDP協議與代理IP介紹
  • 携程旅行 登录分析
  • windows系统如何检查是否开启了mongodb服务