为什么Java的TreeSet没有规定它的类型参数必须扩展Comparable?
eg 当第二个对象添加到 TreeSet 时,下面的代码将引发 ClassCastException。难道TreeSet不能写成类型参数只能是Comparable类型吗? ie TreeSet 无法编译,因为对象不可比较。这样泛型实际上就完成了它们的工作——类型安全。
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String [] args) {
TreeSet<Object> t = new TreeSet<Object>();
t.add(new Object());
t.add(new Object());
}
}
e.g. The code below throws a ClassCastException when the second Object is added to the TreeSet. Couldn't TreeSet have been written so that the type parameter can only be a Comparable type? i.e. TreeSet would not compile because Object is not Comparable. That way generics actually do their job - of being typesafe.
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String [] args) {
TreeSet<Object> t = new TreeSet<Object>();
t.add(new Object());
t.add(new Object());
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
TreeSet
不要求其类型参数为Comparable
,因为它可以采用外部Comparator
来比较非Comparable
代码>值。TreeSet
doesn't require its type parameter to beComparable
, because it can take an externalComparator
for comparing non-Comparable
values.如果类型必须是可比较的,则无法创建具有不可比较类型和比较器的 TreeSet(现在可以)。
在保持类型安全的情况下解决此问题的一种方法是拥有两个类:一个具有可比较的类型参数,另一个具有不可比较的类型参数,并且没有默认构造函数(仅采用比较器的构造函数),但我假设java开发人员不想引入两个基本上做同样事情的类(尽管一个类可以很容易地实现为另一个类的包装器)。
另一种(可以说是更干净的方法)是扩展类型系统,以便某些构造函数仅在与某些类型参数一起使用时才存在(即默认构造函数仅在类型参数可比较时才存在),但我认为这会使泛型成为对于java来说系统太复杂了。
If the type would have to be Comparable, you couldn't create a TreeSet with a non-comparable type and a Comparator (which you can as it is now).
One way to fix this while still being type-safe would have been to have two classes: one with a comparable type parameter and one with a non-comparable type parameter and no default constructor (only the constructor that takes a Comparator), but I suppose the java devs didn't want to introduce two classes that basically did the same thing (though one could easily be implemented as a wrapper around the other).
Another (and arguably cleaner way) would be to extend the type system so that certain constructors only exist when used with certain type parameters (i.e. the default constructor only exists if the type parameter is comparable), but I suppose that would have made the generic system too complex for java.
这是因为该值不一定必须实现 Comparable。您可以显式地向集合传递一个
Comparator
对象,在这种情况下,元素类型不需要是Comparable
。That's because the value does not necessarily have to implement
Comparable
. You can pass the set aComparator
object explicitly, in which case the element type does not need to be aComparable
.您还可以使用
Comparator
作为构造函数参数来创建一个TreeSet
。那么你的物品就不必具有可比性。You can also create a
TreeSet
with aComparator
as constructor parameter. Then your items do not have to be comparable.