-2

I have a class Student which does not implement Comparable.

Case 1: I created a TreeSetof Student objects. mySet.add(s1) does not throw error at compile time, but throws error at runtime. (I could find explanations for this eg: this)

Student s1= new Student(12,"ABCD");
Student s2= new Student(2,"EFGH");
Set<Student> mySet=new TreeSet<Student>();
mySet.add(s1);//shows error only at run time

Case 2: I created an ArrayList of Student objects and tried to sort using Collections.sort(myList). Now, this shows an error at compile time itself.

Student s1= new Student(12,"ABCD");
Student s2= new Student(2,"EFGH");
List<Student> myList=new ArrayList<Student>();
myList.add(s1);
myList.add(s2);
Collections.sort(myList); //shows error in the IDE

Why is there a difference in the two cases?

Sreehari S
  • 388
  • 1
  • 12

3 Answers3

2

That's because TreeSet needs to conform to the specifications of Set (which allows non-Comparable elements), whereas Collections.sort() doesn't and can use Comparable in the signature to make sure it's being caught at compile time.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • 'TreeSet mySet=new TreeSet();' . Why can't TreeSet add more constraints on top of what it inherited from 'Set'? (Sorry if the question is silly) – Sreehari S Jul 17 '18 at 11:54
2

Why is there a difference in the two cases?

Because these are distinct methods of different classes : java.util.Collections.sort() and java.util.Set.add().

Collections.sort() expects a List of Comparable :

public static <T extends Comparable<? super T>> void sort(List<T> list) {
    list.sort(null);
}

Whereas the compilation error as you don't pass a List but a Set. Besides even if you passed a List it would not work as Student is not a Comparable

While TreeSet implements the Collection.add() method that accepts any type matching to the generic of the collection :

public class TreeSet<E> ... {
    ...
    public boolean add(E e) {
            return m.put(e, PRESENT)==null;
    }
    ...
}

Passing a Student to add() being valid for a Set<Student> declared variable, so the compilation passes.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • Couldn't it have been better if there is a check for 'Comparable' in the add(E e) method of TreeSet you pasted above? – Sreehari S Jul 17 '18 at 12:00
1
Set<Student> mySet = new TreeSet<Student>();
mySet.add(s1);//shows error only at run time

mySet is a Set and could be a HashSet: Set.add cannot require that the added element is a Comparable. As add on a HashSet could go by Object.hashCode. The compiler does not do an analysis that the actual Set is a TreeSet.

One could do:

SortedSet<Student> mySet

And as said by others Collections.sort requires the elements to be comparable to be sortable.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138