List to TreeSet转换产生:“java.lang.ClassCastException:MyClass不能转换为java.lang.Comparable”

时间:2010-03-24 01:32:46

标签: java classcastexception

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包含不必要的重复项。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

如果您只是想要删除重复项,请使用HashSet,尽管这会以随机的方式随机播放Iterator返回的对象的顺序。
但是如果你想稍微保留订单,请使用LinkedHashSet,这至少会保留列表的插入顺序。

TreeSet仅适用于您需要Set排序的对象,可以是对象的Comparable实现,也可以是传递给Comparator的自定义TreeSet's构造