HashMap with Null Key and Null Value

115,098

Solution 1

HashMap does not call hashcode when null is passed as key and null Key is handled as special case.

Put Method

HashMap puts null key in bucket 0 and maps null as key to passed value. HashMap does it by linked list data structure. HashMap uses linked list data structure internally.

Linked list data structure used by HashMap (a static class in HashMap.java)

static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        final int hash;
}

In Entry class the K is set to null and value mapped to value passed in put method.

Get Method

While in Hashmap get method the checks if key is passed as null. Search Value for null key in bucket 0.

Hence there can only be one null key in one hashmap object.

Solution 2

If you pass null as map key, it will go to 0 bucket. All values of null key will go there. That is why it returns same value, cause all keys you are providing are null and are in the same bucket of your HashMap.

Solution 3

Incase of null key , Hashmap implementation consider it as special case and doesnot call hashCode method instead it stores Entry object to 0 bucket location.

Solution 4

A HashMap can only store one value per key. If you want to store more values, you have to use a MultivalueHashMap (Google Guava and Apache Commons Collections contain implementations of such a map).

e1 and e2 have the value null, since you don't assign any object to them. So if you use those variables, the key of that map entry is also null, which leads to your result. Null doesn't have any hashcode, but is tolerated as key in the HashMap (there are other Map implementations which don't allow Null as key).

Solution 5

When you put NULL to HashMap there is special check if you are trying to put NULL as key (called putForNullKey()). It is special case and works not like you are trying to put some object which is not null, and as you may see it even doesn't go to hash calculation.

public V put(K key, V value) {
    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

private V putForNullKey(V value) {
    for (Entry<K,V> e = table[0]; e != null; e = e.next) {
        if (e.key == null) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
    modCount++;
    addEntry(0, null, value, 0);
    return null;
}
Share:
115,098
Nizam
Author by

Nizam

Updated on July 21, 2022

Comments

  • Nizam
    Nizam almost 2 years

    Consider the following Code :

    import java.util.*;
    
    class Employee {
    
        String name;
    
        public Employee(String nm) {
            this.name=nm;
        }
    }
    
    public class HashMapKeyNullValue {
    
        Employee e1;
    
        public void display(){
    
            Employee e2=null;
            Map map=new HashMap();
    
            map.put(e2, "25");
            System.out.println("Getting the Value When e2 is set as KEY");
            System.out.println("e2 : "+map.get(e2));
            System.out.println("e1 : "+map.get(e1));
            System.out.println("null : "+map.get(null));
    
            map.put(e1, "");
            System.out.println("Getting the Value when e1 is set as KEY");
            System.out.println("e2 : "+map.get(e2));
            System.out.println("e1 : "+map.get(e1));
            System.out.println("null : "+map.get(null));
    
            map.put(null, null);   // null as key and null as value
            System.out.println("Getting the Value when setting null as KEY and null as value");
            System.out.println("e2 : "+map.get(e2));
            System.out.println("e1 : "+map.get(e1));
            System.out.println("null : "+map.get(null));
    
            map.put(null, "30");
            System.out.println("Getting the Value when setting only null as KEY");
            System.out.println("e2 : "+map.get(e2));
            System.out.println("e1 : "+map.get(e1));
            System.out.println("null : "+map.get(null));
        }
    
        public static void main(String[] args) {
    
            new HashMapKeyNullValue().display();
    
        }
    }
    

    The Output of program is :

    Getting the Value When e2 is set as KEY
    e2 : 25
    e1 : 25
    null : 25
    Getting the Value when e1 is set as KEY
    e2 : 
    e1 : 
    null : 
    Getting the Value when setting null as KEY and null as value
    e2 : null
    e1 : null
    null : null
    Getting the Value when setting only null as KEY
    e2 : 30
    e1 : 30
    null : 30
    

    Here how e1, e2, and null as keys are related to each other. Is all three are assigned to same hashcode ? If yes, WHY ?

    Since all three seems to be look different the change in one value changes the other. Does it mean that only one entry for key is being made into HashMap either e1, e2, or null beacause all treated to be like the same key.