列表到 TreeSet 转换产生:“java.lang.ClassCastException:MyClass 不能转换为 java.lang.Comparable”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2504803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 08:35:13  来源:igfitidea点击:

List to TreeSet conversion produces: "java.lang.ClassCastException: MyClass cannot be cast to java.lang.Comparable"

javaclasscastexception

提问by Chuck

List<MyClass> myclassList = (List<MyClass>) rs.get();

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

I don't understand why this code generates this:

我不明白为什么这段代码会生成这个:

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

MyClass does not implement Comparable. I just want to use a Set to filter the unique elements of the List since my List contains unncessary duplicates.

MyClass 没有实现 Comparable。我只想使用 Set 来过滤 List 的唯一元素,因为我的 List 包含不必要的重复项。

采纳答案by polygenelubricants

Does MyClass implements Comparable<MyClass>or anything like that?

有没有MyClass implements Comparable<MyClass>或类似的东西?

If not, then that's why.

如果没有,那就是原因。

For TreeSet, you either have to make the elements Comparable, or provide a Comparator. Otherwise TreeSetcan't function since it wouldn't know how to order the elements.

对于TreeSet,您要么必须制作元素Comparable,要么提供Comparator. 否则TreeSet无法运行,因为它不知道如何对元素进行排序。

Remember, TreeMap implements SortedSet, so it has to know how to order the elements one way or another.

请记住,TreeMap implements SortedSet,因此它必须知道如何以一种或另一种方式对元素进行排序。

You should familiarize yourself with how implementing Comparabledefines natural orderingfor objects of a given type.

您应该熟悉实现如何为给定类型的对象Comparable定义自然顺序

The interface defines one method, compareTo, that must return a negative integer, zero, or a positive integer if this object is less than, equal to, or greater than the other object respectively.

该接口定义了一个方法,compareTo如果此对象分别小于、等于或大于另一个对象,则该方法必须返回负整数、零或正整数。

The contract requiresthat:

合同要求

  • sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
  • it's transitive: x.compareTo(y)>0 && y.compareTo(z)>0implies x.compareTo(z)>0
  • x.compareTo(y)==0implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z))for all z
  • 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

Additionally, it recommendsthat:

此外,它还建议

  • (x.compareTo(y)==0) == (x.equals(y)), i.e. "consistent with equals
  • (x.compareTo(y)==0) == (x.equals(y)),即“符合 equals

This may seem like much to digest at first, but really it's quite natural with how one defines total ordering.

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



If your objects can not be ordered one way or another, then a TreeSetwouldn't make sense. You may want to use a HashSetinstead, which have its own contracts. You are likely to be required to @Override hashCode()and equals(Object)as appropriate for your type (see: Overriding equals and hashCode in Java)

如果您的对象不能以一种或另一种方式排序,那么 aTreeSet就没有意义。您可能想要使用 aHashSet代替,它有自己的合同。您可能需要@Override hashCode()并且equals(Object)适合您的类型(请参阅:在 Java 中覆盖 equals 和 hashCode

回答by Jeff Storey

If you don't pass an explicit Comparatorto a TreeSet, it will try to compare the objects (by assuming they are Comparable). And if they aren't Comparable, it cannot compare them, so this exception is thrown!
TreeSetsare sorted sets and require either objects to be Comparableor a Comparatorto be passed in to determine how to sort the objects in the Set.

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

回答by Yishai

If you just want the set to remove duplicates, used a HashSet, although that will shuffle the order of the objects returned by the Iteratorin ways that appear random.
But if you want to preserve the order somewhat, use LinkedHashSet, that will at least preserve the insertion order of the list.

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

TreeSetis only appropriate if you need the Setsorted, either by the Object's implementation of Comparableor by a custom Comparatorpassed to the TreeSet'sconstructor.

TreeSet仅当您需要Set通过对象的实现ComparableComparator传递给TreeSet's构造函数的自定义进行排序时才合适。