简体   繁体   English

为什么Hashtable不带空键?

[英]Why does Hashtable not take null key?

Why does Hashtable not take a null key? 为什么Hashtable不采用null键?

Also why does HashMap allow null keys? 为什么HashMap允许null键?

What is the purpose of making these two classes Key behaviour so different? 使这两个类的目的是什么?Key行为如此不同?

From the Hashtable JavaDoc : 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.

In a nutshell, since null isn't an object, you can't call .equals() or .hashCode() on it, so the Hashtable can't compute a hash to use it as a key. 简而言之,由于null不是对象,因此不能在其上调用.equals().hashCode() ,因此Hashtable无法计算哈希值以将其用作键。

HashMap is newer, and has more advanced capabilities, which are basically just an improvement on the Hashtable functionality. HashMap更新,并且具有更高级的功能,这基本上只是对Hashtable功能的改进。 As such, when HashMap was created, it was specifically designed to handle null values as keys and handles them as a special case. 因此,在创建HashMap时,它专门设计为将null值作为键处理并将其作为特殊情况处理。

Specifically, the use of null as a key is handled like this when issuing a .get(key) : 具体来说,在发出.get(key)时,使用null作为键是这样处理的:

(key==null ? k==null : key.equals(k))

It is just an implementation detail. 这只是一个实现细节。

Hashtable is the older class, and its use is generally discouraged. Hashtable是较旧的类,通常不鼓励使用它。 Perhaps they saw the need for a null key, and more importantly - null values, and added it in the HashMap implementation. 也许他们看到需要一个null键,更重要的是 - null值,并将其添加到HashMap实现中。

Hashtable predates the collections framework, and was part of JDK 1.0. Hashtable早于集合框架,是JDK 1.0的一部分。 At that time null keys were probably considered not useful or not essential, and were thus forbidden. 那时,空键可能被认为是无用的或不是必需的,因此被禁止。 You might see it as a design error, just as the choice of the name Hashtable rather than HashTable . 您可能会将其视为设计错误,就像选择名称Hashtable而不是HashTable

Then, several years later, came the collections framework, and Hashtable was slightly modified to fit into the framework. 然后,几年后,收集框架,Hashtable稍作修改,以适应框架。 But the behavior on null keys was not changed to keep backward compatibility. 但是没有更改null键上的行为以保持向后兼容性。

Hashtable should be deprecated, IMHO. 应该弃用Hashtable,恕我直言。

I will let you know how the hashmap stores the objects internally: 我会让你知道hashmap如何在内部存储对象:

HashMap stores the values through put(key,value) and gets the values thorugh get(key) . HashMap通过put(key,value)存储值,并获取值get(key) The process follows the concept of Hashing. 该过程遵循Hashing的概念。

When we say put(key,value) - Internally hashCode() for the key is calculated and being taken as the input for hashfunction() to find the bucket location for storing. 当我们说put(key,value) - 计算密钥的内部hashCode()并将其作为hashfunction()的输入来查找存储的存储区位置。

In case of Collision - while calculating the hashcode() there may be a possibility the key is different but the hashcode() is same, at that time after finding out the bucket location the storing is done in the linked list. 在碰撞的情况下 - 在计算hashcode() ,可能存在密钥不同但hashcode()相同的可能性,此时在找到存储桶位置之后,存储在链表中完成。 Please Note - While storing as the Map.Entry both the key-value is stored. 请注意 - 存储为Map.Entry时,存储键值。

When Retrieve of the value through key is done then if during the collision where the key's hashcode() may be same then the value is retrived though equals() function to find out the desired key's value. 当通过key检索值时,如果在碰撞期间密钥的hashcode()可能相同,则通过equals()函数重新获取该值以找出所需的密钥的值。

Regards, Anand 问候,阿南德

Apart from all the details given in other answers, this is how hashmap allow NULL Keys. 除了在其他答案中给出的所有细节之外,这是hashmap允许NULL键的方式。 If you look at the method putForNullKey() in Hashmap (JDK 5) , it reserves the index "0" for the null key. 如果查看Hashmap(JDK 5)中的方法putForNullKey() ,它会为null键保留索引“0”。 All values for the null key are kept inside the "0" index of the array. null键的所有值都保存在数组的“0”索引中。

There is nothing special about storing NULL value as all the put and lookup operations work based on the Key object. 存储NULL值没有什么特别之处,因为所有put和lookup操作都基于Key对象工作。

In hashtable, Java does not have these mechanisms and hence hashtable does not support NULL key or values. 在散列表中,Java没有这些机制,因此散列表不支持NULL键或值。

They're two separate classes for two different things. 它们是两个不同的类,分为两个不同的东西。 Also, HashTable is synchronized. 此外,HashTable是同步的。 HashTable also came before HashMap, so naturally it would be less advanced. HashTable也出现在HashMap之前,所以很自然它会不那么先进。 It probably didn't make sense to generate a null hashcode in early Java. 在早期的Java中生成空哈希码可能没有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM