11
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 的唯一元素,因为我的 List 包含不必要的重复项。

4

3 回答 3

18

是这样吗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

乍一看,这似乎很容易消化,但实际上定义总排序是很自然的。


如果您的对象不能以一种或另一种方式排序,那么 aTreeSet就没有意义了。您可能想改用 a HashSet,它有自己的合同。您可能需要@Override hashCode()equals(Object)根据您的类型(请参阅:Overriding equals and hashCode in Java

于 2010-03-24T01:36:36.827 回答
2

如果您不将显式传递Comparator给 a TreeSet,它将尝试比较对象(假设它们是Comparable)。如果它们不是Comparable,则无法比较它们,因此会引发此异常!
TreeSets是已排序的集合,需要传入ComparableComparator传入对象来确定如何对 . 中的对象进行排序Set

于 2010-03-24T01:36:01.650 回答
1

如果您只是希望该集合删除重复项,请使用 a HashSet,尽管这会以Iterator随机方式返回的对象的顺序打乱。
但是,如果您想在一定程度上保留顺序,请使用LinkedHashSet,这至少会保留列表的插入顺序。

TreeSet仅当您需要Set排序时才合适,无论是通过对象的实现Comparable还是通过Comparator传递给TreeSet's构造函数的自定义。

于 2010-03-24T01:51:05.633 回答