ImmutableList不扩展List?

时间:2015-04-08 02:30:49

标签: java collections gs-collections

当我深入研究ImmutableList的gs-collection源代码时,它不会扩展java.util.List。但是,类javadoc提到All ImmutableList实现必须实现java.util.List

为什么必须要求实施实施java.util.List而不是ImmutableList本身来扩展java.util.List

1 个答案:

答案 0 :(得分:12)

为什么不ImmutableList延长List

ImmutableCollection不会延伸java.util.Collection(而ImmutableList不会延伸java.util.List),因为Collection具有add()等变异方法1}}和remove()。如果不可变集合具有这些方法,则它们总是必须抛出UnsupportedOperationException。对于不可变集合的用户,将自动完成选择中的add()remove()视为可调用方法会很奇怪。

为什么Javadoc强制要求所有ImmutableList实施都实施List的合同?

归结为平等。 ImmutableList应该等于List,假设两个列表在相同的顺序中具有相同的内容。 List.equals() imposes a Javadoc contract声明:

  

当且仅当指定的对象也是列表时才返回true   列表具有相同的大小,以及所有相应的元素对   这两个名单是相同的。

"指定的对象也是一个列表是什么意思?"我们可以在AbstractList.equals()中看到它意味着instanceof List

public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;
    ...
}

因此,所有ImmutableList实现都必须为List实现equals()以对称方式工作。不可变集合工厂已经隐藏了实现细节,例如ImmutableSingletonList实现了具有单个元素的不可变列表。它最终隐藏了List界面。

ImmutableList class diagram

<强>互操作

此设计的一个好处是ImmutableList可以转换为List,这对于与现有API互操作非常重要。

// Library method - cannot refactor the parameter type
public void printAll(List<?> list)
{
    for (Object each : list)
    {
        System.out.println(each);
    }
}

ImmutableList<Integer> immutableList = Lists.immutable.with(1, 2, 3);
List<Integer> castList = immutableList.castToList();
printAll(castList);
// also works
printAll((List<?>) immutableList);

// throws UnsupportedOperationException
castList.add(4);

注意:我是GS Collections的开发人员。