HashSet插入重复值流程分析

本文探讨了Java中HashSet如何处理重复值的问题,通过源码分析发现HashSet底层使用HashMap,当尝试添加重复值时,实际上是对HashMap的put操作,如果返回null则表示插入成功,否则说明已有该值并被覆盖。HashSet的值存储在key中,通过键值对的value(PRESENT对象)进行判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

声明

本人也是小白,只是好奇HashSet插入重复值java是怎样判断的,如果文中存在错误请各位指出,感谢.

测试代码

版本JDK1.8

HashSet<Integer> set = new HashSet();
set.add(11);
set.add(22);
set.add(33);

set.add(22);

分析

源码分析

  1. 查看HashSet源码

    其中一个构造方法

    public HashSet() {
        map = new HashMap<>();
    }
    

    根据源码可以看的HashSet底层其实是使用了HashMap

    再来看所使用的add方法

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
    

    也是直接调用的HashMap中的方法,使用put存放键值对,e很明显是我们传入的值,PRESENT是什么呢?为什么是==null?

    private static final Object PRESENT = new Object();
    

    我的理解:PRESENT 只是个占位的,在put中无关键作用?但在remove方法中会判断map.remove(o)==PRESENT来判断是否成功删除

  2. 查看HashMap源码
    根据putVal方法上的注释@return previous value, or null if none如果插入位置为空返回null,否则返回上一个元素
    所以HashSet中使用==null,返回为空就插入成功

    public V put(K key, V value) {
    	//调用putVal方法
        return putVal(hash(key), key, value, false, true);
    }
    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
      	.....................
    }
    

断点调试

set.add(22);

先将基本类型转为包装类
在这里插入图片描述
计算key的hash值
在这里插入图片描述
进入putVal方法
在这里插入图片描述
进入else,先判断当前位置的值与要插入的值相等在这里插入图片描述
覆盖旧Value,Value都为PRESENT ,返回value,不为null插入失败,add返回false;
在这里插入图片描述

总结

  1. HashSet底层使用HashMap实现.
  2. HashSet的值是存储在key中的.
  3. HashSet中插入重复值相当于将数组中元素与插入数组的元素的value进行了覆盖并返回旧value,两者的value值是相同的,都为PRESENT .
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值