Java HashSet疑问:为何添加new Integer(1000)与1000仅存一个元素?
为什么HashSet添加
1000和new Integer(1000)后只保留一个元素? 这是个很典型的Java集合类问题,咱们一步步拆解清楚背后的逻辑:
首先得明确HashSet判断元素重复的规则:
- 当你尝试向HashSet添加新元素时,它会先计算该元素的
hashCode()值 - 如果这个哈希码和集合中已存在元素的哈希码相同,会进一步调用
equals()方法比较两个元素的内容 - 只有当哈希码相同且equals返回true时,HashSet才会认为这是重复元素,不会将其加入集合
接下来看你代码里的两个操作:
hs.add(1000):这里是Java的自动装箱特性,int类型的1000会被自动转换成Integer对象,等价于调用Integer.valueOf(1000)hs.add(new Integer(1000)):通过new关键字确实创建了一个全新的Integer对象,它的内存地址和前一个对象是不同的
那为什么HashSet会把它们判定为同一个元素?核心在于Integer类重写了hashCode()和equals()方法:
- hashCode():Integer的hashCode直接返回它包装的int值本身。所以不管是
Integer.valueOf(1000)还是new Integer(1000),它们的hashCode都是1000,完全一致。 - equals():Integer的equals方法比较的是两个对象包装的int数值,而不是对象的内存地址。所以这两个对象调用equals时,因为数值都是1000,会返回
true。
结合HashSet的判断规则,这两个元素哈希码相同且equals返回true,所以第二个new Integer(1000)会被判定为重复元素,不会被添加到集合中,最终输出自然是[1000]。
额外补充:Java对-128到127之间的Integer有缓存机制,Integer.valueOf()会复用缓存中的对象,但即使是超出这个范围的数值(比如1000),只要值相同,hashCode()和equals()的结果依然一致,HashSet还是会判定为重复元素——缓存只是影响对象是否复用,不改变HashSet的重复判断逻辑。
内容的提问来源于stack exchange,提问作者pawarchinmay27
相关产品推荐
相关产品推荐

