Преобразование списка в набор деревьев приводит к:“java.язык программирования.ClassCastException:MyClass не может быть приведен к java.lang.Сопоставимый”
-
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
конструктор.