0

I try to add objects of Employee class to a TreeSet. I don't implement Comparable or Comparator interface. But the add method code behaves differently in different systems. Why so? Code snippet below:-

import java.util.Set;
import java.util.TreeSet;

public class TreeSetTest {
public static void main(String[] args) {

    Set<Employee> set = new TreeSet<Employee>();
    set.add(new Employee());
//  set.add(new Employee());
//  set.add(new Employee());
 }
}

On the current system (Win 10), whether I write set.add() method once or thrice. It always throws ClassCastException at runtime. But talking of this question- Why does TreeSet throws ClassCastException The user there has written, that he doesn't get exception when he uses add method only once.

Also, in another system (Win 7), yesterday I had tried adding object 3 times, calling set method thrice, and there is no ClassCastException!! The size of set remains 1 only, so it appeared that multiple objects are just NOT getting added to set.

So what could be the reason for different-different kind of behavior of add method?

Community
  • 1
  • 1
shanti
  • 270
  • 1
  • 4
  • 20
  • 1
    If anything, it would be the JRE version, not the Windows version. – shmosel Jun 17 '16 at 04:06
  • @shmosel yes, so I guess different window version will have different JREs as well. – shanti Jun 17 '16 at 04:09
  • They may or they may not. Why don't you check? – shmosel Jun 17 '16 at 04:09
  • @TimBiegeleisen Yes, I just copy-pasted it from my system. Win 10 running Java 8, but project running on 1.6 version. – shanti Jun 17 '16 at 04:10
  • 2
    If you already know the cause of the error, namely not implementing `Comparable` _or_ providing a custom comparator during construction, then why ask the question? Note that a comparison for ordering doesn't actually need to be done until adding the _second_ item. Maybe there is a slight change in implementation between Java 6 and Java 8. In any case, you should not be using a sorted set without some notion of a comparator present. – Tim Biegeleisen Jun 17 '16 at 04:11
  • @TimBiegeleisen because I am interested to know the internal behaviour – shanti Jun 17 '16 at 04:14

1 Answers1

4

TreeSet.add() delegates to TreeMap.put(), which has differing behavior in Java 6 and Java 8.

Java 6:

public V put(K key, V value) {
    Entry<K,V> t = root;
    if (t == null) {
        // TBD:
        // 5045147: (coll) Adding null to an empty TreeSet should
        // throw NullPointerException
        //
        // compare(key, key); // type check
        root = new Entry<K,V>(key, value, null);
        size = 1;
        modCount++;
        return null;
    }
    ...

Java 8:

public V put(K key, V value) {
    Entry<K,V> t = root;
    if (t == null) {
        compare(key, key); // type (and possibly null) check

        root = new Entry<>(key, value, null);
        size = 1;
        modCount++;
        return null;
    }
    ...

As you can see, the earlier version had the compare() line commented out for some reason, but it was added back in the later version. Hence the exception you're seeing for the first element.

See here also: Why TreeSet can be used as a key for TreeMap in jdk 1.6?

Community
  • 1
  • 1
shmosel
  • 49,289
  • 6
  • 73
  • 138
  • Interesting. Thanks for that. Let me read the implementation detail of the classes, to have more clarity. – shanti Jun 17 '16 at 04:42
  • Thanks a lot for this answer. I had a quick look at the implementation of TreeMap class and you are perfectly right about this. In Java 6, the compare method is commented, but it is uncommented in Java 7 and 8. So it will throw ClassCastException in Java 7 and 8, but not in 6. – shanti Jun 18 '16 at 03:45