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