Список преобразования TreeSet производит: "java.lang.ClassCastException: MyClass нельзя отнести к java.lang.Comparable"

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 для фильтрации уникальных элементов List, так как в моем списке есть лишние дубликаты.

Ответ 1

Есть ли MyClass implements Comparable<MyClass> или что-то в этом роде?

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

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

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

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

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

Контракт требует, чтобы:

  • sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
  • it transitive: 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) в зависимости от вашего типа (см. Переопределение равных и хэш-код в Java)

Ответ 2

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

Ответ 3

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

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