9

I thought that null is allowed for a Set.
So why does the following code:

SortedSet<Integer> set = new TreeSet<Integer>();  
set.add(null);  
set.add(1);  //--->Line indicated by exception  

Gives the following exception?

Exception in thread "main" java.lang.NullPointerException at
java.lang.Integer.compareTo(Unknown Source) at
java.lang.Integer.compareTo(Unknown Source) at
java.util.TreeMap.put(Unknown Source) at
java.util.TreeSet.add(Unknown Source)

Cratylus
  • 52,998
  • 69
  • 209
  • 339

4 Answers4

20

Yes, you can. But you will have to provide your own Comparator to handle the case when null is compared to any other contents of your set. With natural ordering applied, Java objects do not know how to compare themselves to null. Inversely, null doesn't know how to compare itself with any object as you cannot call null.compareTo(object).

An example implementation of such a "null-safe" Comparator can be found in the apache commons-collections library. Check out the NullComparator. You could use it as such:

// Unfortunately no support for Java generics yet, in commons-collections
@SuppressWarnings("unchecked")
SortedSet<Integer> set = new TreeSet<Integer>(new NullComparator());  
set.add(null);  
set.add(1);
Ignatius
  • 2,745
  • 2
  • 20
  • 32
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • @Lukas Eder can we do same thing for TreeMap also? In java 7 TreeMap & TreeSet both are changed(http://bugs.java.com/view_bug.do?bug_id=5045147). – Aashutosh Shrivastava Oct 01 '14 at 08:31
  • @AashutoshShrivastava: I think this should be best answered in a new Stack Overflow question. Feel free to create one. – Lukas Eder Oct 01 '14 at 17:45
  • Thanks @Lukas Eder. I am using NullComparator() same as you mention above & its working fine. TreeMap< Integer, String> tree1= new TreeMap<>(new NullComparator()); tree1.put(null, "aashu"); – Aashutosh Shrivastava Oct 06 '14 at 06:47
6

the API of TreeSet (http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html#add(E)) says that add will throw a NPE:

if the specified element is null and this set uses natural ordering, or its comparator does not permit null elements

so if you want to store null you have to provide a Comparator which can deal with this an knows where null stands compared to 0 or all other values.

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
Korgen
  • 5,191
  • 1
  • 29
  • 43
2

Instead of creating a Comparator you can create your own "null" value.

static final Integer NULL = Integer.MIN_VALUE;

set.add(NULL):
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 2
    This may be an unacceptable approach, given that all integer values have a meaning. If the numbers being used are limited to a particular range, than this approach may be acceptable. – Zéychin Jul 23 '12 at 07:54
  • 2
    MIN_VALUE is the least likely to be useful as has odd properties like `x == -x && x != 0` ;) Its not often that every single`int` value is needed, but it is using a `Long` instead could be an option. – Peter Lawrey Jul 23 '12 at 08:01
  • Hah, I never thought about `x == -x` for `MIN_VALUE`. That's pretty surprising when two's complement isn't your primary field of expertise... – Lukas Eder Jul 23 '12 at 08:04
  • 2
    Same for Long.MIN_VALUE and Character.MIN_VALUE (which is 0 ;) but not Short.MIN_VALUE, Byte.MIN_VALUE, Float.MIN_VALUE or Double.MIN_VALUE. – Peter Lawrey Jul 23 '12 at 08:08
  • 1
    You keep amazing me with this [arcane Java trickery, that you keep posting](http://stackoverflow.com/a/8710747/521799). – Lukas Eder Jul 23 '12 at 08:20
  • 1
    @LukasEder Cheers, I will take that as a complement. :) – Peter Lawrey Jul 23 '12 at 08:38
0

You can't insert null values into the TreeSet. From JDK 1.7 onwards null is not accepted into a TreeSet. Insertion of null value into TreeSet will throw NullPointerException reason being while insertion of null, it gets compared to the existing elements and null can't be compared to any value. Till JDK 1.6, the first element insertion can be null but any more null element will result in NullPointerException.

If you have to add null, in that case you have to write your own custom comparator to handle null or either use NullComparator() provided by commons-collections.

Harleen
  • 773
  • 3
  • 15
  • 25