Collections.sort() показывает ошибку во время компиляции, а метод add() в TreeSet показывает во время выполнения

У меня есть класс Student, который не реализует Comparable.

Случай 1: я создал TreeSetиз Student объектов. mySet.add(s1) не выдает ошибку во время компиляции, но выдает ошибку во время выполнения. (Я мог бы найти объяснения этому, например: исключение-скорее" title="это">это)

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

Случай 2: я создал ArrayList из Student объектов и попытался выполнить сортировку с помощью Collections.sort(myList). Теперь это показывает ошибку во время компиляции.

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

Почему есть разница в двух случаях?


person Sreehari S    schedule 17.07.2018    source источник
comment
А ошибки есть?   -  person Thorbjørn Ravn Andersen    schedule 17.07.2018
comment
случай 1: java.lang.ClassCastException: студент не может быть приведен к java.lang.Comparable (время выполнения) случай 2: метод sort(List‹T›) в типе Collections неприменим для аргументов (Set‹Student›)   -  person Sreehari S    schedule 17.07.2018
comment
Разве Collections.sort() не относится только к List?   -  person Prashant    schedule 17.07.2018
comment
список также показывает ту же ошибку   -  person Sreehari S    schedule 17.07.2018


Ответы (3)


Это связано с тем, что TreeSet должен соответствовать спецификациям Set (что позволяет несопоставимые элементы), тогда как Collections.sort() не соответствует и может использовать Comparable в подписи, чтобы убедиться, что он перехватывается во время компиляции.

person Kayaman    schedule 17.07.2018
comment
'TreeSet‹Student› mySet=new TreeSet‹Student›();' . Почему TreeSet не может добавить больше ограничений поверх того, что он унаследовал от «Set»? (извините, если вопрос глупый) - person Sreehari S; 17.07.2018

Почему есть разница в двух случаях?

Потому что это разные методы разных классов: java.util.Collections.sort() и java.util.Set.add().

Collections.sort() ожидает List из Comparable :

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

В то время как ошибка компиляции, поскольку вы передаете не List, а Set. Кроме того, даже если бы вы прошли List, это не сработало бы, так как Student не является Comparable.

В то время как TreeSet реализует метод Collection.add(), который принимает любой тип, соответствующий универсальному элементу коллекции:

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

Передача Student в add() действительна для объявленной переменной Set<Student>, поэтому компиляция проходит успешно.

person davidxxx    schedule 17.07.2018
comment
Разве не было бы лучше, если бы в методе add(E e) TreeSet, который вы вставили выше, была проверка «Comparable»? - person Sreehari S; 17.07.2018

Set<Student> mySet = new TreeSet<Student>();
mySet.add(s1);//shows error only at run time

mySet является набором и может быть HashSet: Set.add не может требовать, чтобы добавленный элемент был Comparable. Поскольку add в HashSet может идти по Object.hashCode. Компилятор не анализирует, является ли фактический набор TreeSet.

Можно было бы сделать:

SortedSet<Student> mySet

И, как говорят другие, Collections.sort требует, чтобы элементы были сопоставимы, чтобы их можно было сортировать.

person Joop Eggen    schedule 17.07.2018