2010-04-13 61 views
9

例如当第二个对象被添加到TreeSet时,下面的代码抛出一个ClassCastException异常。无法编写TreeSet以便类型参数只能是Comparable类型? TreeSet不会编译,因为Object是不可比较的。这种方式实际上是他们的工作 - 类型安全。为什么Java的TreeSet没有指定它的类型参数必须扩展Comparable?

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()); 
    } 
} 

回答

4

如果类型必须是Comparable,则无法创建具有非可比较类型和Comparator的TreeSet(您可以像现在这样)。

解决这个问题的一种方法仍然是类型安全的,它将有两个类:一个具有可比较的类型参数,另一个具有非可比较类型参数并且没有默认构造函数(只有构造函数需要Comparator ),但我想java开发人员不想引入两个基本上做同样事情的类(尽管可以很容易地将其实现为另一个包装)。另一种(也可以说是更干净的方式)将扩展类型系统,以便某些构造函数只在与某些类型参数一起使用时才存在(即,如果类型参数可比较,则仅存在默认构造函数),但是我想这会已经使java的通用系统过于复杂。

+0

感谢您的全面回答。大声笑,我认为通用系统已经够复杂了! – Tarski 2010-04-13 19:22:42

13

TreeSet不需要其类型参数为Comparable,因为它可以采取外部Comparator用于比较非Comparable值。

+0

啊谢谢。我想没有办法指定对无参数构造函数的限制,以便它只能使用可比较对象?是否有更好的设计有两个类 - 一个采用Comparable类型参数,另一个采用任何类型参数,但构造函数必须采用Comparators? – Tarski 2010-04-13 19:12:30

+4

@Tarski:'TreeSet'在1.2中添加。泛型在1.5中加入。 – 2010-04-13 19:25:54

1

这是因为值而不是必然必须执行Comparable。您可以明确传递一个Comparator对象,在这种情况下,元素类型不需要是Comparable

0

您还可以使用Comparator作为构造函数参数创建一个TreeSet。那么你的物品不必是可比的。

相关问题