List 到 TreeSet 的转换会产生:“java.lang.ClassCastException:MyClass 无法转换为 java.lang.Comparable”
-
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))
, , IE。“是一致的equals
一开始这似乎可以消化很多,但实际上,它可以定义总订购方式很自然。
如果您的物品无法以某种方式订购,那么 TreeSet
没有意义。您可能想使用 HashSet
相反,它们有自己的合同。您可能需要 @Override hashCode()
和 equals(Object)
适合您的类型(请参阅: 在 Java 中重写 equals 和 hashCode)
其他提示
如果您没有通过显式Comparator
到TreeSet
,它会尝试比较对象(假设他们是Comparable
)。如果他们不Comparable
,也不能对它们进行比较,所以这会引发异常!点击
TreeSets
排序集和要求任一物体被Comparable
或Comparator
要传递在确定如何在Set
的对象进行排序。
如果你只是想设置的删除重复,使用HashSet
,尽管这将洗牌在出现随机的方式Iterator
返回的对象的顺序。点击
但是,如果你想有所保留的顺序,使用LinkedHashSet
,至少会保留列表的插入顺序。
TreeSet
仅当您需要的Set
分类合适,可以通过对象的实现Comparable
的或传递给Comparator
构造定制TreeSet's
。