为什么Hashtable没有使用null
密钥?
为什么HashMap允许null
个密钥?
使这两个类的目的是什么?Key行为如此不同?
答案 0 :(得分:28)
来自Hashtable
JavaDoc:
To successfully store and retrieve objects from a hashtable, the objects used
as keys must implement the hashCode method and the equals method.
简而言之,由于null
不是对象,因此您无法在其上调用.equals()
或.hashCode()
,因此Hashtable
无法计算hash用它作为密钥。
HashMap
较新,并且具有更高级的功能,这基本上只是对Hashtable
功能的改进。因此,在创建HashMap
时,它专门用于处理null
值作为键并将其作为特殊情况处理。
具体而言,在null
发出.get(key)
时,(key==null ? k==null : key.equals(k))
作为关键字的使用会像这样处理:
{{1}}
答案 1 :(得分:5)
这只是一个实施细节。
Hashtable
是较旧的类,通常不鼓励使用它。也许他们认为需要一个null键,更重要的是 - null值,并将其添加到HashMap
实现中。
答案 2 :(得分:5)
Hashtable早于集合框架,是JDK 1.0的一部分。那时,空键可能被认为是无用的或不是必需的,因此被禁止。您可能会将其视为设计错误,就像选择名称Hashtable
而非HashTable
一样。
然后,几年后,收集框架,Hashtable稍作修改,以适应框架。但是null键上的行为没有改变以保持向后兼容性。
Hashtable应该被弃用,恕我直言。
答案 3 :(得分:3)
我会让你知道hashmap如何在内部存储对象:
HashMap通过put(key,value)存储值,并获取值get(key)
。该过程遵循Hashing的概念。
当我们说put(key,value)
时 - 计算密钥的内部hashCode()
,并将其作为hashfunction()
的输入,以查找要存储的存储区位置。
在碰撞的情况下 - 在计算hashcode()
时,可能存在密钥不同但hashcode()
相同的可能性,此时在找到存储桶位置后,存储在链表。请注意 - 存储为Map.Entry时,存储键值。
当通过键检索值时,如果在碰撞期间密钥的hashcode()可能相同,则通过equals()
函数重新获取该值以找出所需密钥的值。
此致 阿南德
答案 4 :(得分:1)
除了在其他答案中给出的所有细节之外,这是hashmap允许NULL键的方式。如果查看Hashmap(JDK 5)中的方法putForNullKey()
,它会为null键保留索引“0”。 null键的所有值都保存在数组的“0”索引中。
存储NULL值没有什么特别之处,因为所有put和lookup操作都基于Key对象工作。
在哈希表中,Java没有这些机制,因此哈希表不支持NULL键或值。
答案 5 :(得分:0)
它们是两个不同的两个不同的类。此外,HashTable是同步的。 HashTable也出现在HashMap之前,所以很自然它会不那么先进。在早期的Java中生成空哈希码可能没有意义。