These Sets allow null. Why can't I add null elements?

nakul picture nakul · Feb 8, 2013 · Viewed 90k times · Source

I want to know why HashSet, LinkedHashSet and TreeSet implementation does not allow null elements? Whenever i try to run the following code it throws a null pointer exception.

public static void main(String[] args) {

    HashSet<Integer> hashSet = new HashSet<Integer>();

    hashSet.add(2);
    hashSet.add(5);
    hashSet.add(1);
//  hashSet.add(null);  will throw null pointer 
    hashSet.add(999);
    hashSet.add(10);
    hashSet.add(10);
    hashSet.add(11);
    hashSet.add(9);
    hashSet.add(10);
    hashSet.add(000);
    hashSet.add(999);
    hashSet.add(0);

    Iterator<Integer> it = hashSet.iterator();
    while(it.hasNext()){
        int i = it.next();
        System.out.print(i+" ");
    }
    }

Please guide me.

Answer

Perception picture Perception · Feb 8, 2013

This is why I don't like to rely on auto-boxing. Java Collections cannot store primitives (for that you will need a third party API like Trove). So, really, when you execute code like this:

hashSet.add(2);
hashSet.add(5);

What is really happening is:

hashSet.add(new Integer(2));
hashSet.add(new Integer(5));

Adding a null to the hash set is not the problem, that part works just fine. Your NPE comes later, when you try and unbox your values into a primitive int:

while(it.hasNext()){
    int i = it.next();
    System.out.print(i+" ");
}

When the null value is encountered, the JVM attempts to unbox it into an the int primitive, which leads to an NPE. You should change your code to avoid this:

while(it.hasNext()){
    final Integer i = it.next();
    System.out.print(i+" ");
}