Преобразование List в TreeSet создает: «java.lang.ClassCastException: MyClass не может быть приведен к java.lang.Comparable». - PullRequest
11 голосов
/ 24 марта 2010
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. Я просто хочу использовать набор для фильтрации уникальных элементов списка, так как мой список содержит ненужные дубликаты.

Ответы [ 3 ]

18 голосов
/ 24 марта 2010

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 )

2 голосов
/ 24 марта 2010

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

1 голос
/ 24 марта 2010

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

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

...