This week's book giveaway is in the Programmer Certification forum.
We're giving away four copies of OCP Oracle Certified Professional Java SE 11 Programmer I Study Guide: Exam 1Z0-815 and have Jeanne Boyarsky & Scott Selikoff on-line!
See this thread for details.
Win a copy of OCP Oracle Certified Professional Java SE 11 Programmer I Study Guide: Exam 1Z0-815 this week in the Programmer Certification forum!
  • 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
  • Liutauras Vilda
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Devaka Cooray
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Ron McLeod
  • Carey Brown
Bartenders:
  • Paweł Baczyński
  • Piet Souris
  • Vijitha Kumara

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: 3812
64
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: 66235
250
  • 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: 3812
64
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: 66235
250
  • 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: 66235
250
  • 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: 3812
64
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: 66235
250
  • 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: 66235
250
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prints “null” as the first element

Thank you
 
Martin Vashko
Sheriff
Posts: 3812
64
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: 21817
104
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: 66235
250
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
…and that is why we were getting the exceptions.

Thank you again
 
Then YOU must do the pig's work! Read this tiny ad. READ IT!
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!