声明
本人也是小白,只是好奇HashSet插入重复值java是怎样判断的,如果文中存在错误请各位指出,感谢.
测试代码
版本JDK1.8
HashSet<Integer> set = new HashSet();
set.add(11);
set.add(22);
set.add(33);
set.add(22);
分析
源码分析
-
查看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来判断是否成功删除 -
查看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;

总结
- HashSet底层使用HashMap实现.
- HashSet的值是存储在key中的.
- HashSet中插入重复值相当于将数组中元素与插入数组的元素的value进行了覆盖并返回旧value,两者的value值是相同的,都为
PRESENT.
本文探讨了Java中HashSet如何处理重复值的问题,通过源码分析发现HashSet底层使用HashMap,当尝试添加重复值时,实际上是对HashMap的put操作,如果返回null则表示插入成功,否则说明已有该值并被覆盖。HashSet的值存储在key中,通过键值对的value(PRESENT对象)进行判断。
172万+





