Why Hashtable does not allow null keys or values?

76,047

Solution 1

Hashtable is the older class, and its use is generally discouraged. Perhaps they saw the need for a null key, and more importantly - null values, and added it in the HashMap implementation.

HashMap is newer, and has more advanced capabilities, which are basically just an improvement on the Hashtable functionality. When HashMap was created, it was specifically designed to handle null values as keys and handles them as a special case.

Edit

From 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.

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.

Solution 2

The main reason why Hashtable and ConcurrentHashMap do not allow null keys or values is because of the expectation that they are going to be used in a multi-threaded environment. For a minute, let's assume that null values are allowed. In this case the hashtable's "get" method has ambiguous behavior. It can return null if the key is not found in the map or it can return null if the key is found and its value is null. When a code expects null values, it usually checks if the key is present in the map so that it can know whether the key is not present or the key is present but value is null. Now this code breaks in a multi-threaded environment. Let's take a look at below code:

if (map.contains(key)) {
    return map.get(key);
} else {
    throw new KeyNotFoundException;
}

In the above code, let's say thread t1 calls the contains method and finds the key and it assumes that key is present and is ready for returning the value whether it is null or not. Now before it calls map.get, another thread t2 removes that key from the map. Now t1 resumes and returns null. However as per the code, the correct answer for t1 is KeyNotFoundException because the key has been removed. But still it returns the null and thus the expected behavior is broken.

Now, for a regular HashMap, it is assumed, that it is going to get called by a single thread, hence there is no possibility of key getting removed in the middle of "contains" check and "get". So HashMap can tolerate null values. However for Hashtable and ConcurrentHashMap, the expectations are clear that multiple threads are going to act on the data. Hence they cannot afford to allow null values and give out incorrect answer. Same logic goes for keys. Now the counter argument can be - the contains and get steps could fail for non null values for Hashtables and ConcurrentHashMaps, because another thread can modify the map/table before the second step gets executed. That is correct, it can happen. But since Hashtables and ConcurrentHashMaps do not allow null keys and values, it is not necessary for them to implement contains and get check in the first place. They can directly get the value because they know that if the get method returns null, the only reason for that is the key is not present and not because the value could be null. The contains and get check is necessary only for HashMaps because they allow the null values and thus need to resolve the ambiguity about whether the key is not found or the value is null.

Solution 3

The reason is the reason on the accepted answer: Hashtable is old.

However, the use of Hashtable IS NOT discouraged in favor of HashMap in every scenario.

  • Hashtable is synchronized, so it is THREAD-SAFE. HashMap is not.

Neither Hashtable nor ConcurrentHashMap support null keys or values. HashMap does.

If you want a drop-in replacement that doesn't require anything else than changing the class and works in every scenario, there is none. The most similar option would be ConcurrentHashMap (which is thread safe but doesn't support locking the whole table):

This class is fully interoperable with Hashtable in programs that rely on its thread safety but not on its synchronization details.

HashMap is a better replacement for single threaded applications or any time synchronization is not a requirement, because of the performance impact synchronization introduces.

Sources:

Solution 4

Default Hashtable implementation has null check which thorws null pointer exception. Later on java developers might have realized the importance of null keys(for some default value etc) and values and that why HashMap got introduced.

For HashMap, null check is there for keys if the key is null then that element will be stored in a location where hashcode is not required.

Solution 5

so to conclude

Because in HashTable when you put an element it will take into account key and value hash. Basically you will have something like :

public Object put(Object key, Object value){

    key.hashCode();

    //some code

    value.hashCode();

}

HashTable - Does not allow null keys This is because, in put(K key, V value) method, we have key.hashcode() which throws null pointer exception. HashTable - Does not allow null value This is because, in put(K key, V value) method we have if(value==null){throw new NullPointerException

HashMap allows null values as it doesn't have any checks like HashTable, while it allows only one null key. This is done with the help of putForNullKey method, which add the value to the 0th index of the internal Array every time the key is provided as null

Share:
76,047
Love Hasija
Author by

Love Hasija

Updated on December 14, 2021

Comments

  • Love Hasija
    Love Hasija over 2 years

    As specified in JDK documentation, Hashtable does not allow null keys or values. HashMap allows one null key and any number of null values. Why is this?

  • DaoWen
    DaoWen almost 12 years
    ConcurrentHashMap is a newer class but also has the restriction of not allowing null keys or values. They add this restriction for performance reasons since it's a lot of extra work to support null keys and values but probably not useful the majority of the time.
  • Carlos Verdes
    Carlos Verdes about 8 years
    ConcurrentHashMap put: Maps the specified key to the specified value in this table. Neither the key nor the value can be null. Please, review your answer.
  • NotGaeL
    NotGaeL about 8 years
    oops! Thank you for the heads up! I went for the obvious and thought the only difference between ConcurrentHashMap and HashMap was thread safety. Not the first time it has happened. What an akward naming convention!
  • Sujal Mandal
    Sujal Mandal almost 8 years
    The class name is java.util.Hashtable not "HashTable" !
  • Kumar Abhishek
    Kumar Abhishek over 7 years
    From the Answer i was expecting a reason for Why Hashtable does not allows null keys or values ? Although you are suggesting newer and older.
  • rustyx
    rustyx almost 6 years
    Nonsense. Hashtable never calls value.hashCode().
  • Admin
    Admin over 4 years
    i think because hashtable is syncronized,it can't hold or lock null object