Экземпляр TreeSet в Задать ссылочную переменную - PullRequest
5 голосов
/ 06 марта 2019

Для кода:

Set<Phone> set = new TreeSet<>();
set.add(new Phone("Harry"));

Я получаю сообщение об ошибке:

Телефон не может быть преобразован в java.base / java.lang.Comparable

Почему Phone должен реализовать Comparable, если ссылочная переменная имеет тип Set?

Если ссылочной переменной было TreeSet, то, конечно, класс Phone должен реализовывать Comparable.

Ответы [ 3 ]

4 голосов
/ 06 марта 2019

Посмотрите на Javadoc для TreeSet():

Создает новый пустой набор деревьев, отсортированный в соответствии с естественным порядком его элементов. Все элементы, вставленные в набор, должны реализовывать интерфейс Comparable.

Элементы должны быть как-то сопоставимы, потому что TreeSet - это SortedSet. Обратите внимание, что Set не обязательно неупорядочены, просто интерфейс Set не определяет порядок. Реализующим классам разрешено определять порядок элементов.

Если вы хотите вставить несовместимые экземпляры в компаратор (или использовать ненатуральное упорядочение), вы должны вызвать конструктор с явным компаратором.

Set <Phone> set = new TreeSet<>(someComparator);
1 голос
/ 06 марта 2019

Фактический тип имеет значение только.Это TreeSet, основанное на TreeMap, которое работает с Comparable с, если не указан другой компаратор.

Вы можете определить компаратор на основе, например, свойства Phone.Это устранит необходимость реализации Comparable для Phone.

Set<Phone> set = new TreeSet<>(Comparator.comparing(Phone::getModel));
1 голос
/ 06 марта 2019

Хотя ссылочный тип Set, фактическая реализация по-прежнему TreeSet, поэтому вызывается метод TreeSet.add(). Проверка параметров происходит во время выполнения, когда вызывается ThreeSet.add() и вы получаете исключение:

Exception in thread "main" java.lang.ClassCastException: 
    class java.lang.Object cannot be cast to class java.lang.Comparable
...