Преобразование списка в набор деревьев приводит к:“java.язык программирования.ClassCastException:MyClass не может быть приведен к java.lang.Сопоставимый”

StackOverflow https://stackoverflow.com/questions/2504803

  •  22-09-2019
  •  | 
  •  

Вопрос

List<MyClass> myclassList = (List<MyClass>) rs.get();

TreeSet<MyClass> myclassSet = new TreeSet<MyClass>(myclassList);

Я не понимаю, почему этот код генерирует это:

java.lang.ClassCastException: MyClass cannot be cast to java.lang.Comparable

MyClass не реализует Comparable .Я просто хочу использовать Set для фильтрации уникальных элементов списка, поскольку мой список содержит ненужные дубликаты.

Это было полезно?

Решение

Делает MyClass implements Comparable<MyClass> или что-нибудь в этом роде?

Если нет, то вот почему.

Для TreeSet, вы либо должны создать элементы Comparable, или предоставить Comparator.В противном случае TreeSet не может функционировать, так как он не знал бы, как упорядочить элементы.

Запомни, TreeMap implements SortedSet, поэтому он должен знать, как упорядочивать элементы так или иначе.

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

Интерфейс определяет один метод, compareTo, который должен возвращать отрицательное целое число, ноль или положительное целое число, если этот объект меньше, равен или больше другого объекта соответственно.

Контракт требует это:

  • sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
  • это переходный процесс: x.compareTo(y)>0 && y.compareTo(z)>0 подразумевает x.compareTo(z)>0
  • x.compareTo(y)==0 подразумевает , что sgn(x.compareTo(z)) == sgn(y.compareTo(z)) для всех z

Кроме того, это рекомендует это:

  • (x.compareTo(y)==0) == (x.equals(y)), т. е."согласуется с equals

Сначала может показаться, что это слишком сложно переварить, но на самом деле это вполне естественно с учетом того, как определяется общий порядок.


Если ваши объекты не могут быть упорядочены тем или иным способом, то TreeSet это не имело бы смысла.Возможно, вы захотите использовать HashSet вместо этого, у которых есть свои собственные контракты.Скорее всего, от вас потребуется @Override hashCode() и equals(Object) в зависимости от вашего типа (см.: Переопределение equals и hashCode в Java)

Другие советы

Если вы не передадите явное Comparator к a TreeSet, он попытается сравнить объекты (предполагая , что они Comparable).А если это не так Comparable, он не может сравнить их, поэтому генерируется это исключение!
TreeSets являются отсортированными наборами и требуют, чтобы либо объекты были Comparable или a Comparator которые будут переданы для определения того, как сортировать объекты в Set.

Если вы просто хотите, чтобы набор удалял дубликаты, используйте HashSet, хотя это приведет к изменению порядка объектов , возвращаемых Iterator способами, которые кажутся случайными.
Но если вы хотите несколько сохранить порядок, используйте LinkedHashSet, это, по крайней мере, сохранит порядок вставки списка.

TreeSet подходит только в том случае, если вам нужен Set отсортированы либо по реализации объекта, либо Comparable или по обычаю Comparator переданный в TreeSet's конструктор.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top