HashSet实现中的Null对象

jam*_*jam 10 java hashset

在Java API中,HashSet的实现是使用Object作为内部HashMap的值,

   // Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}
Run Code Online (Sandbox Code Playgroud)

但是HashMap允许它的值为null.我认为没有必要填补价值,为什么需要这样做?

Jim*_*son 12

因为HashSet合同规定remove()返回true指定的对象是否存在,并且已被删除.为此,它使用wrapped HashMap#remove()返回已删除的值.

如果你要存储null而不是一个对象,那么HashMap#remove()将返回的调用将null与尝试删除不存在的对象的结果无法区分,并且HashSet.remove()无法满足合同.


Jon*_*eet 6

但是HashMap允许它的值为null

当价值完全由HashSet?控制时,为什么会这么重要?这确保了与密钥相关的唯一值PRESENT.因此,如果map.put返回null,那可能只是因为之前没有该键的条目.

值就在那里,因为必须指定一些值,如果值指定为null,那将是坏的 - 这将使得在调用之前判断是否存在值更难add.如果你要指定任何非空值,你也可以强制它一直是相同的值 - 例如,你不希望它阻止垃圾收集.

现在,如果你问的HashSet是为什么实现HashMap而不是一个根本不记录价值的更有效的实现,那是一个不同的问题,而我没有答案.