尽管SortedSet是接口而不是类,为什么要向SortedSet添加元素

时间:2012-12-16 10:47:58

标签: java interface sortedset

有人可以解释一下为什么这段代码编译并运行正常,尽管SortedSet是一个接口而不是一个具体的类:

public static void main(String[] args) {

    Integer[] nums = {4, 7, 8, 14, 45, 33};

    List<Integer> numList = Arrays.asList(nums);
    TreeSet<Integer> numSet = new TreeSet<Integer>();
    numSet.addAll(numList);

    SortedSet<Integer> sSet = numSet.subSet(5, 20);
    sSet.add(17);
    System.out.println(sSet);

}

它通常打印结果:[7, 8, 14, 17]

此外,由于SortedSet无法实现(预期),因此我更加惊讶。这行不编译:

SortedSet<Integer> sSet = new SortedSet<Integer>();

但是,如果我尝试代码:

public static void main(String[] args) {

    Integer[] nums = {4, 7, 8, 14, 45, 33};

    List<Integer> numList = Arrays.asList(nums);
    numList.add(56);

    System.out.println(numList);
}

它会抛出一个UnsupportedOperationException。我估计,这来自List是一个接口而不能作为具体类处理的事实。 SortedSet的真实情况如何?

4 个答案:

答案 0 :(得分:3)

SortedSet是一个界面。这意味着您可以引用实现此接口的类,但不能创建没有implmenetation的类实例。

在Arrays.asList()的情况下,它返回一个包装原始数组的类。您无法添加到原始阵列,因此不支持添加。例如,如果使用set,则将更改原始数组。

答案 1 :(得分:1)

List<Integer> numList = Arrays.asList(nums);

Array.asList()在List界面中返回数组换行。所以列表仍然由数组支持,并且数组是固定大小,您不能添加/删除数组中的元素。这就是为什么下一行会抛出异常UnsupportedOperationException

有关更多详细信息,java ArrayList仍然是一个数组,但它有一些帮助方法,您可以删除/添加元素(您可以使用wiki作为短语resizeable array以获取更多详细信息。

其次,SortedSet是一个接口。像抽象类这样的接口可以引用一个实现/扩展它的类,但它不是具体类,所以你不能在那些(接口或抽象类)上创建对象。

我知道,你提出的两个问题,可能都与OOP中的polymorphism有关,我也建议你使用wiki这句话。

希望这有帮助:)

答案 2 :(得分:0)

SortedSet是一个接口而不是一个类。

你只能从非抽象类中实例化。

列表也是一个界面。 但是根据List的文档,“add”方法是可选的,这意味着没有保证可以得到支持。

我认为可选方法与接口的概念和契约相矛盾。 最好的方法是使用NonModifyableList(不添加)和ModifyableList(使用add)。 目前糟糕的选择可能是历史和不打破旧代码的结果。

答案 3 :(得分:0)

如果我理解正确,您就会问为什么可以成功将对象引用为SortedSet(或任何接口类型)。当变量的类型是接口或抽象类时,这意味着变量必须包含一个继承该变量类型(或null对象)的对象。

虽然每个对象的实际类型必须是具体类,但sSet变量只需要保存某个继承(实现)SortedSet的类的实例。

对于TreeSet.subSet方法,它返回一个对象,其类型是一个内部定义的具体类,它实现了SortedSet。