我知道set使用map<k,v>的实现,其中set元素是键。但是价值观会怎样呢?他们使用 private static final Object PRESENT = new Object() 作为每个键的常量值。很酷。但为什么呢?这意味着对于每个键,我们将存储我们永远不会使用的值,这样我们就可以重用map的实现?为什么?他们就不能做关键的实现吗?那个常数是用过了还是只是“坐”在那里?
private static final Object PRESENT = new Object()
piok6c0g1#
如实现中所述,如果您可以看到返回布尔值的hashset的add方法。这个 add 方法调用 put(key, PRESENT) 在内部 HashMap . 这个 remove 方法调用 remove(key) 在内部 HashMap ,但它必须返回 boolean 指示是否存在密钥。如果 null 作为值存储,然后 HashSet 我需要打电话 containsKey 首先,然后 remove ,以确定密钥是否存在--额外的开销。在这里,只有一个内存开销 Object ,这是非常小的。
add
put(key, PRESENT)
HashMap
remove
remove(key)
boolean
null
HashSet
containsKey
Object
public boolean add(E e) { return map.put(e, PRESENT)==null; }
ktca8awb2#
对于hashset中每个可能包含条目的“place”,必须能够判断该位置是否被占用。如果您想像hashset那样支持键值null,那么就不能使用key=null作为“notused”指示符。因为需要使用key.equals()在集合中查找对象,所以不能有一个特殊的key对象意外地等于(不完全相同)实际的key。因此,你需要一个单独的标志,除了关键说,是否'的地方'被占领。这就像是一个对象引用一样;然后可以重用map实现。
2条答案
按热度按时间piok6c0g1#
如实现中所述,如果您可以看到返回布尔值的hashset的add方法。
这个
add
方法调用put(key, PRESENT)
在内部HashMap
. 这个remove
方法调用remove(key)
在内部HashMap
,但它必须返回boolean
指示是否存在密钥。如果null
作为值存储,然后HashSet
我需要打电话containsKey
首先,然后remove
,以确定密钥是否存在--额外的开销。在这里,只有一个内存开销Object
,这是非常小的。ktca8awb2#
对于hashset中每个可能包含条目的“place”,必须能够判断该位置是否被占用。
如果您想像hashset那样支持键值null,那么就不能使用key=null作为“notused”指示符。因为需要使用key.equals()在集合中查找对象,所以不能有一个特殊的key对象意外地等于(不完全相同)实际的key。
因此,你需要一个单独的标志,除了关键说,是否'的地方'被占领。这就像是一个对象引用一样;然后可以重用map实现。