我知道Set使用Map<K、 V>,其中Set元素是键。但是值会发生什么?他们使用private static final Object PRESENT = new Object()
作为每个键的常数值。
酷。但为什么呢?这意味着,对于每个键,我们都将存储我们永远不会使用的值,这样我们就可以重用Map?为什么?难道他们就不能实现Key吗?这个常数曾经被使用过吗?或者它只是"坐"在那里?
正如在实现中提到的,如果您可以看到HashSet的add方法返回布尔值。
add
方法在内部HashMap
上调用put(key, PRESENT)
。remove
方法在内部HashMap
上调用remove(key)
,但它必须返回一个指示密钥是否存在的boolean
。如果null
被存储为值,那么HashSet
将需要首先调用containsKey
,然后调用remove
,以确定密钥是否存在——这是额外的开销。这里,只有一个Object
的内存开销,这是非常小的。
public boolean add(E e)
{
return map.put(e, PRESENT)==null;
}
对于可以在HashSet中保存一个条目的每个潜在"位置",必须能够判断该位置是否被占用。
如果你想支持null的键值,就像HashSet所做的那样,那么你就不能使用key=null作为"未使用";指示信号由于您需要使用key.equals((来查找集合中的对象,因此不能有一个特殊的键对象意外地等于(不等于(实际的键。
因此,除了键之外,您还需要一个单独的标志来说明"位置"是否被占用。这可能和其他任何东西一样是一个对象引用;然后可以重用Map实现。