我知道Hashtable中不允许使用null键,因为必须将元素存储在Hashtable中。但是,如果key为null,则将无法计算null key的哈希码。但是我不明白,但是Sun开发人员不允许使用null值的确切原因是什么。
有人说在put方法实现中没有对值的空检查,这就是为什么它抛出NullPointerException的原因。但是我的问题是为什么要进行空值检查。其背后是否有任何特定原因。
我读了很多书,但没有满意的答案。有人说如果存在null值,并且如果您尝试使用get()方法检索值,则会产生歧义,它将返回null,并且此null是因为实际值为null或缺少键,这就是为什么null不能预测原因的原因。所以我需要有答案的精确答案。
答案 0 :(得分:1)
如果这样做,您将获得NULL值
hashtable.get("key")
“键”不在地图中,则无需存储空值。
如果您将能够存储null,那么您将永远不知道所拥有的内容: 空映射 ,或者是 缺少映射 em> 。
答案 1 :(得分:1)
Hashtable
被认为是旧代码。您应该使用HashMap
,它允许null
作为值,并且一个键可以是null
。
编辑
经过更深入的搜索后,我可能会提出这样的决定。 Hashtable
已同步(而HashMap
未同步)。
来自JavaDoc:
与新的集合实现不同,
Hashtable
是同步的。如果不需要线程安全的实现,建议使用HashMap
代替Hashtable
。如果需要线程安全的高并发实现,则建议使用ConcurrentHashMap
代替Hashtable
。
您可以看到Hashtable
的后继者不是我以前写的HashMap
,而是ConcurrentHashMap
。 ConcurrentHashMap
不允许不允许null
使我感到惊讶。我开始挖掘并发现this:
From the author of ConcurrentHashMap himself (Doug Lea):
ConcurrentMaps(
ConcurrentHashMaps
,ConcurrentSkipListMaps
)中不允许使用null的主要原因是,无法容纳在非并行映射中几乎无法容忍的歧义。最主要的是,如果map.get(key)
返回null
,则无法检测到密钥是否显式映射到null
,而密钥没有被映射。在非并发映射中,可以通过map.contains(key)
进行检查,但是在并发映射中,两次调用之间的映射可能已更改。
所以也许Hashtable
的作者与ConcurrentHashMap
的作者具有相同的原因
答案 2 :(得分:0)
要成功地从哈希表存储和检索对象, 用作键的对象必须实现hashCode方法,并且等于 方法
Null不是对象,因此无法在其上调用.equals()或.hashCode(),因此Hashtable无法计算哈希值以将其用作键
哈希表containsValue(Object value)函数如果该值为null,则抛出NullPointerException,因此对于该值也不允许为null
答案 3 :(得分:0)
将空值设为 still 在HashMap
中被认为是错误的决定,新的Map
类和java-9
中的静态工厂方法证明:< / p>
Map.of("test", null)
将抛出NulPointerException