• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Jeanne Boyarsky
  • Junilu Lacar
  • Henry Wong
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Frits Walraven
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • salvin francis
  • fred rosenberger

TreeSet adding null twice

 
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a question related to q50 of the Examlab practice exam 4:

Why does adding null a second time to a TreeSet create a NullpointerException?

public static void main(String[] args) {
Set ts = new TreeSet();
ts.add(null);
ts.add(null); // creates NullPointerException
}

Shouldn't the second null simply replace the first?
Or is the reason that null cannot be compared to anything?


public static void main(String[] args) {
Set ts = new TreeSet();
ts.add(1);
ts.add(null); // creates NullPointerException
ts.add(null);
}


public static void main(String[] args) {
Set ts = new TreeSet();
ts.add("String");
ts.add(null); // creates NullPointerException
ts.add(null);
}

The last two cases fail sooner, on the first ts.add(null), presumably because Integer and null are not Comparable, nor are String and null.

Is it correct therefore that the first case fails because null also cannot be compared to null?

Many thanks in advance!
JG
 
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The distinct case, common to all three examples you've posted, is adding a null value to a non-empty TreeSet. This is when the NullPointerException happens.

When adding an element to a TreeSet, the implementation has to find a place for the item being inserted. When there aren't any item present yet (ie. when the TreeSet is empty), there isn't any comparison to do and the item is simply placed into the set as a root of the tree. However, when the set isn't empty, a position for the new item must be found, and this is done by comparing the new item with items already in the set. This is the problem, since TreeSet constructed without a custom comparator uses the Comparable.compareTo() method for these comparisons, and these methods by definition cannot handle null values.

It is possible to construct a TreeSet to which a null value can be placed, by using a custom comparator which correctly handles null values (that is, compares two nulls as being the same, and compares nulls to non-null values consistently).
 
Marshal
Posts: 69410
276
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is an interesting phenomenon! I can't find anything about it in the TreeSet documentation. Under the natural ordering link, however, we can find this:-

e.compareTo(null) should throw a NullPointerException

 
Martin Vashko
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The documentation of TreeSet is somewhat lacking in this aspect. The possibility of using a null-permitting comparator is only indirectly referred to in documentation of several methods (such as TreeSet.add()), where it states the following:

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

 
Campbell Ritchie
Marshal
Posts: 69410
276
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think that is an unfortunate inconsistency the API writers have. Sometimes they mention null prohibitions in the method descriptions and sometimes only once in the heading of the class. String is a bad example of the latter.
 
Campbell Ritchie
Marshal
Posts: 69410
276
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried this on JDK8u40If I uncomment any of the lines 23 27 or 29 I seem to get an Exception.
 
Martin Vashko
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:If I uncomment any of the lines 23 27 or 29 I seem to get an Exception.


Is that unexpected? You haven't provided a custom comparator to the TreeSet constructor which would gracefully handle nulls.

In Java 8, you can try this:

(Disclaimer: haven't tried it myself. One has to love the Java 8's default methods, though. )
 
Campbell Ritchie
Marshal
Posts: 69410
276
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I hadn't expected an Exception on an empty Set. I shall try your code and see what happens.
 
Campbell Ritchie
Marshal
Posts: 69410
276
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prints “null” as the first element

Thank you
 
Martin Vashko
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I hadn't expected an Exception on an empty Set.


Oh, I haven't understood you get the exception on that very statement.

Interesting. Looks like a check was added in some newer version of Java. I guess they do an additional check on inserting the first element, such as comparing it to itself. I'll have a look into the JDK sources later.
 
Sheriff
Posts: 21949
106
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since at least Java 7 (possibly earlier, can't check), TreeMap.put (which is being used by TreeSet.add) starts like this:
So if the map is empty (the root is null), the key is indeed compared to itself.
 
Campbell Ritchie
Marshal
Posts: 69410
276
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
…and that is why we were getting the exceptions.

Thank you again
 
Can't .... do .... plaid .... So I did this tiny ad instead:
Devious Experiments for a Truly Passive Greenhouse!
https://www.kickstarter.com/projects/paulwheaton/greenhouse-1
    Bookmark Topic Watch Topic
  • New Topic