声明
本人也是小白,只是好奇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
.