为什么Hashtable不允许为空值?

时间:2018-08-14 12:54:29

标签: java

我知道Hashtable中不允许使用null键,因为必须将元素存储在Hashtable中。但是,如果key为null,则将无法计算null key的哈希码。但是我不明白,但是Sun开发人员不允许使用null值的确切原因是什么。

有人说在put方法实现中没有对值的空检查,这就是为什么它抛出NullPointerException的原因。但是我的问题是为什么要进行空值检查。其背后是否有任何特定原因。

我读了很多书,但没有满意的答案。有人说如果存在null值,并且如果您尝试使用get()方法检索值,则会产生歧义,它将返回null,并且此null是因为实际值为null或缺少键,这就是为什么null不能预测原因的原因。所以我需要有答案的精确答案。

4 个答案:

答案 0 :(得分:1)

如果这样做,您将获得NULL值

hashtable.get("key")

“键”不在地图中,则无需存储空值。

如果您将能够存储null,那么您将永远不知道所拥有的内容: 空映射 ,或者是 缺少映射 em> 。

答案 1 :(得分:1)

Hashtable被认为是旧代码。您应该使用HashMap,它允许null作为值,并且一个键可以是null

编辑

经过更深入的搜索后,我可能会提出这样的决定。 Hashtable已同步(而HashMap未同步)。

来自JavaDoc

  

与新的集合实现不同,Hashtable是同步的。如果不需要线程安全的实现,建议使用HashMap代替Hashtable。如果需要线程安全的高并发实现,则建议使用ConcurrentHashMap代替Hashtable

您可以看到Hashtable的后继者不是我以前写的HashMap,而是ConcurrentHashMapConcurrentHashMap 不允许不允许null使我感到惊讶。我开始挖掘并发现this

From the author of ConcurrentHashMap himself (Doug Lea):

  

ConcurrentMaps(ConcurrentHashMapsConcurrentSkipListMaps)中不允许使用null的主要原因是,无法容纳在非并行映射中几乎无法容忍的歧义。最主要的是,如果map.get(key)返回null,则无法检测到密钥是否显式映射到null,而密钥没有被映射。在非并发映射中,可以通过map.contains(key)进行检查,但是在并发映射中,两次调用之间的映射可能已更改。

所以也许Hashtable的作者与ConcurrentHashMap的作者具有相同的原因

答案 2 :(得分:0)

From Java Documentation

  

要成功地从哈希表存储和检索对象,   用作键的对象必须实现hashCode方法,并且等于   方法

Null不是对象,因此无法在其上调用.equals()或.hashCode(),因此Hashtable无法计算哈希值以将其用作键

哈希表containsValue(Object value)函数如果该值为null,则抛出NullPointerException,因此对于该值也不允许为null

答案 3 :(得分:0)

将空值设为 still HashMap中被认为是错误的决定,新的Map类和java-9中的静态工厂方法证明:< / p>

Map.of("test", null)

将抛出NulPointerException