aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes TreeSet adding twice null Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "TreeSet adding twice null" Watch "TreeSet adding twice null" New topic
Author

TreeSet adding twice null

Anton Brass
Greenhorn

Joined: Sep 08, 2010
Posts: 25
I found a question at Nikos Blog, where adding twice null to a TreeSet ends up in an Exception, altough adding it once is fine. Why?



I think I also saw once that adding null to a TreeSet that already have items ends up also in an exception.
Is it possible to add null after "anything" was added? I guess not since it is natural ordering or?

The API isn't really clear about that fact:

[...]
More formally, adds the specified element e to this set if the set contains no element e2 such that (e==null ? e2==null : e.equals(e2))
[...]

Throws
ClassCastException - if the specified object cannot be compared with the elements currently in this set
NullPointerException - if the specified element is null and this set uses natural ordering, or its comparator does not permit null elements
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

You have found a java bug


"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." --- Martin Fowler
Please correct my English.
Seetharaman Venkatasamy
Ranch Hand

Joined: Jan 28, 2008
Posts: 5575

TreeSet is backed by TreeMap . I would suggest you to go through the add method of TreeSet or put method of TreeMap.
Anton Brass
Greenhorn

Joined: Sep 08, 2010
Posts: 25
well I reviewed the API of TreeSet and don't understand it clear enough

Is it really a bug?

What is the expected behavior, never accept a null or? The Problem is, if you put in a null before any object is inside the TreeSet, how the JVM should know if the Comparator that is used in the future (or maybe never) is allowing null or not?
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

Internally the TreeSet uses a TreeMap. And the TreeSet.add() delegates it to TreeMap.put(). Just open the source of that method and you'll see the bug. There is even a comment about the bug.
Shanky Sohar
Ranch Hand

Joined: Mar 17, 2010
Posts: 1051

i run this code on jdk6.0 and it is giving me error.
Could you please tell which jdk you are using


SCJP6.0,My blog Ranchers from Delhi
Huachaitou Peek
Greenhorn

Joined: Aug 07, 2010
Posts: 17
Wouter Oet wrote:Internally the TreeSet uses a TreeMap. And the TreeSet.add() delegates it to TreeMap.put(). Just open the source of that method and you'll see the bug. There is even a comment about the bug.



How can I take a look at source code ? Is there an easy way to do that ? Thanks.
Steli Niculescu
Greenhorn

Joined: Jul 14, 2009
Posts: 14
Huachaitou Peek wrote:
Wouter Oet wrote:Internally the TreeSet uses a TreeMap. And the TreeSet.add() delegates it to TreeMap.put(). Just open the source of that method and you'll see the bug. There is even a comment about the bug.



How can I take a look at source code ? Is there an easy way to do that ? Thanks.

http://lmgtfy.com/?q=TreeSet+docjar&l=1
Harpreet Singh janda
Ranch Hand

Joined: Jan 14, 2010
Posts: 317

This exception is due to the fact that the TreeSet maintains the order of the elements added. Whenever we add an element to the TreeSet it compare the added element with already existing elements to find the correct position of the newly added element.

So if the TreeSet will be empty the first element will be directly added to the TreeSet as there are no elements to be compared.
But if there is any element in the TreeSet, it will through a null pointer exception when newly added element will be compared with the already existing elements (as any operation on a null object throw null pointer exception).
Anton Brass
Greenhorn

Joined: Sep 08, 2010
Posts: 25
Ok thanks, anyway shitty behavior ;)
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

Huachaitou Peek wrote:How can I take a look at source code ? Is there an easy way to do that ? Thanks.

In your java distribution the is a src.zip. Just unzip it and you have the source code.

Harpreet Singh janda wrote:This exception is due to the fact that the TreeSet maintains the order of the elements added. Whenever we add an element to the TreeSet it compare the added element with already existing elements to find the correct position of the newly added element.

So if the TreeSet will be empty the first element will be directly added to the TreeSet as there are no elements to be compared.
But if there is any element in the TreeSet, it will through a null pointer exception when newly added element will be compared with the already existing elements (as any operation on a null object throw null pointer exception).
Although that sounds like a plausible answer and matches with the external behavior, it's not what happens internally.

First of all we're not using a custom comparator thus the natural order is maintained. If you would have provided a custom comparator then the nullpointer will probably occur there.
Internally the TreeSet uses a TreeMap. When you add the first element to it there are no conditions to be met. The key may be null. But when another element is added the code checks for null and in case the key is null then a nullpointer exception is thrown.

So:
add(null); add(null); throws NullPointerException because of the null check
add(null); add("JavaRanch"); throws NullPointerException because the String comparable uses a method of the null value
Harpreet Singh janda
Ranch Hand

Joined: Jan 14, 2010
Posts: 317

It does not matter whether we are using a custom comparator or the one provide by the java itself. If we are not providing a custom comparator then the comparator provided by the java itself will be used (To maintain the natural order).

So whenever we try to ad a null it will throw a NPE because internally the null will be compared with the other values (by custom of the core comparator) and any operation on null produces the NPE.
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

Harpreet Singh janda wrote:It does not matter whether we are using a custom comparator or the one provide by the java itself.
Actually it does. This runs without exceptions:
TreeMap doesn't enforce that the key can't be null if a custom comparator is provided.
Harpreet Singh janda
Ranch Hand

Joined: Jan 14, 2010
Posts: 317

That means NPE is due to the comparator not the internal structure of TreeSet.
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

Harpreet Singh janda wrote:That means NPE is due to the comparator not the internal structure of TreeSet.

That is exactly what I said:
Wouter Oet wrote:So:
add(null); add(null); throws NullPointerException because of the null check
add(null); add("JavaRanch"); throws NullPointerException because the String comparable uses a method of the null value
Harpreet Singh janda
Ranch Hand

Joined: Jan 14, 2010
Posts: 317

So both of us are no the same page
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: TreeSet adding twice null