为什么我被允许这样做:
TreeSet<Object> treeSet = new TreeSet<Object>();
treeSet.add(new Object());
但不是这样:
final List<Object> objects = new ArrayList<Object>();
Collections.sort(objects);
第一个给了我一个ClassCastException,但第二个给了我一个编译错误。据我了解,实际问题在两种情况下都是相同的:java.lang.Object
未实现可比较界面。
更新: 嗯,由于某种原因,这仅适用于Java 7而不是6。 我是愚蠢还是累?有人可以对此有所了解吗?
更新#2: 根据java版本,我得到不同的结果。请看图片:
答案 0 :(得分:5)
最初我在这里皱眉,但你是对的。
SortedSet
界面不会强制您将其通用类型指定为Comparable
,因为TreeSet
还允许您为不Comparator
的类型指定Comparable
1}}。编译器无法区分这两个选项。
答案 1 :(得分:4)
Collections.sort
需要Comparable
列表。 TreeSet
在输入时没有这个限制。使用默认构造函数,文档说它按“元素的自然排序”进行排序。不清楚的是它如何排序Object
,但你的问题涉及打字。
更新:
我错过了问题的最后部分。在没有查看堆栈跟踪的情况下,我猜想由于TreeSet
的默认构造函数尝试按“自然顺序”排序,在内部,它正在执行转换为Comparable
,这会导致{{1} }}
更新:
我仔细查看了ClassCastException
(JDK 6,JDK 7)的javadoc,它说
构造一个新的空树集,根据自然排序 订购其元素。插入集合中的所有元素必须 实现Comparable接口。此外,所有这些元素 必须是相互比较的:e1.compareTo(e2)一定不能扔掉 集合中任何元素e1和e2的ClassCastException。如果是用户 尝试向违反此约束的集合添加元素 (例如,用户尝试将字符串元素添加到其集合中 元素是整数),add调用将抛出ClassCastException。
两者兼而有之。因此,如果JDK6没有发生ClassCastException,也许这是一个错误。
答案 2 :(得分:4)
因为TreeSet<E>
不限于实现Comparable
的对象,因为您可以通过Comparator<E>
构建它。
Collections.sort(T)
需要T
实施Comparable
。 Collections
中有另一种接受任何对象的方法,但您需要提供Comparator
。
最后,这完全取决于您的对象是否具有自然顺序,因为它们实现了Comparable
,或者您为对象提供了必要的Comparator
来完成工作。
答案 3 :(得分:2)
从Collection:
中查看sort函数的签名public static <T extends Comparable<? super T>> void sort(List<T> list)
期望对象实现Comparable接口。这就是为什么你的代码显示编译时错误。
但是在Treeset的情况下,添加的元素没有限制应该实现Comparable.It只需要正常工作。