2010-03-24 27 views
11
List<MyClass> myclassList = (List<MyClass>) rs.get(); 

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

我不明白为什么这个代码生成此:清单TreeSet的转换产生: “java.lang.ClassCastException:MyClass的不能被转换为java.lang.Comparable的”

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

MyClass的呢没有实现可比。我只想使用Set来过滤列表中的独特元素,因为我的列表包含不必要的重复项。

回答

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

这似乎不太像起初消化,但实际上它是很自然的与 如何定义整体排序。


如果你的对象不能被订购一拉上,然后TreeSet就没有意义。您可能需要使用HashSet,因为它们有自己的合同。你可能被要求@Override hashCode()和适合你的类型equals(Object)(见:Overriding equals and hashCode in Java

+0

MyClass没有实现Comparable。我只想使用Set来过滤列表中的独特元素,因为我的列表包含不必要的重复项。 – Chuck 2010-03-24 01:40:54

+2

然后使用HashSet。它不会尝试对元素进行排序。 – 2010-03-24 01:41:26

2

如果您没有将明确的Comparator传递给TreeSet,它会尝试比较对象(通过假设它们是Comparable)。如果它们不是Comparable,它不能比较它们,所以抛出这个异常!
TreeSets是有序集合,要求传入ComparableComparator以确定如何对Set中的对象进行排序。

1

如果你只是想设置的删除重复,使用HashSet,尽管这将洗牌在返回的对象的顺序Iterator以随机出现的方式。
但是,如果您想保持订单的某种程度,请使用LinkedHashSet,这将至少保留列表的插入顺序。

TreeSet如果你需要Set排序,或者由对象的实现Comparable或传递给TreeSet's构造定制Comparator是最合适不过。

相关问题