为什么HashSet的内部实现会创建虚拟对象以在HashMap中作为值插入而不是插入空值?

时间:2015-05-04 18:48:30

标签: java hashmap hashset

HashSet是使用HashMap实现的,当我们向HashSet添加任何东西时,如果e1不在集合中,它会在HashMap内部添加(e1,new Object())。我的问题是为什么他们插入新的Object(),当他们可以插入像(e1,null),这是更优化的方法,因为没有创建新的对象。在这里插入空值有什么缺点吗?

3 个答案:

答案 0 :(得分:12)

每次新密钥HashSet进入地图时,Object都不会添加新的put。它确实使用Object,但每次都使用相同的Object。此值在PRESENT源代码中命名为HashSet

add方法调用内部put(key, PRESENT)上的HashMapremove方法会在内部remove(key)上调用HashMap,但必须返回boolean,表示密钥是否存在。如果将null存储为值,则HashSet需要先调用containsKey,然后调用remove,以确定密钥是否存在 - 额外开销。这里只有一个Object的内存开销,这是非常小的。

答案 1 :(得分:2)

我只是查看了源代码并看到了这段代码

'debug' => false,

如果使用public boolean add(E e) { return map.put(e, PRESENT)==null; } public boolean remove(Object o) { return map.remove(o)==PRESENT; } 代替null,则无效;在每种情况下,都需要额外的步骤。

答案 2 :(得分:0)

E.g。如果您将HashSet对象提供给ConcurrentSkipListSet构造函数,则它不能包含任何空值。