Java ImmutableList不扩展列表?
当我深入研究Java ImmutableList不扩展列表?,java,collections,gs-collections,Java,Collections,Gs Collections,当我深入研究ImmutableList的gs集合源代码时,它没有扩展java.util.List。然而,javadoc类提到所有ImmutableList实现都必须实现java.util.List public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof List)) return false; ... } 为什么必须要求实现来实现ja
ImmutableList
的gs集合源代码时,它没有扩展java.util.List
。然而,javadoc类提到所有ImmutableList实现都必须实现java.util.List
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
...
}
为什么必须要求实现来实现
java.util.List
,而不是ImmutableList
本身来扩展java.util.List
?为什么不ImmutableList
扩展List
?
不扩展java.util.Collection
(也不扩展java.util.List
),因为Collection
具有类似add()
和remove()
的变异方法。如果不可变集合具有这些方法,它们将始终必须抛出UnsupportedOperationException
。对于不可变集合的用户来说,将自动完成选项中的add()
和remove()
视为可调用方法会很奇怪
为什么Javadoc强制要求所有ImmutableList
实现也实现List
?
归根结底是平等。假设两个列表的内容顺序相同,则不可变列表
应该等于列表
。其中指出:
当且仅当指定的对象也是一个列表时返回true,并且
列表具有相同的大小,并且中所有对应的元素对都相同
这两个列表是相等的
“指定的对象也是一个列表”是什么意思?我们可以在AbstractList.equals()
中看到它的意思是instanceof list
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
...
}
因此,所有ImmutableList
实现也必须实现List
,以便equals()
以对称方式工作。immutable集合工厂已经隐藏了实现细节,例如带有单个元素的不可变列表是由ImmutableSingleOnlist
实现的。它还隐藏了列表
接口
互操作
这种设计的一个好处是可以将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);
//库方法-无法重构参数类型
公共void printAll(列表)
{
对于(每个对象:列表)
{
系统输出打印项次(每个);
}
}
ImmutableList ImmutableList=Lists.immutable.with(1,2,3);
List castList=immutableList.castToList();
printAll(castList);
//也有效
printAll((列表)不可变列表);
//抛出不支持的操作异常
增加(4);
注意:我是一名开发人员。它扩展了什么?它从根本上扩展了
java.lang.Iterable
奇怪的设计。他们可以编写extensed java.util.List
并自动执行,而不是将不可执行的需求放入Javadoc中。我同意,这让我头疼,因为我不想使用特定于gs集合的接口。我仍然想使用java.util.List
,而不关心底层的实现。然而,唯一能提供有用答案的人是作者,除非你把他带到这里,否则你所能得到的都是或多或少的不知情的猜测。感谢你的长时间回答,这是有意义的,但我猜这是设计的一种风格。就我个人而言,我更喜欢使用add()和remove()抛出UnsupportedOperationException,而不是调用castToList()。开发人员应该知道,如果代码使用的是ImmutableList,则添加和删除将不起作用,这是开发人员的问题,而不是设计问题。但我想这只是个人意见。再次感谢您的回答我想您可能对UnmodifiableMutableList及其工厂方法MutableList.asUnmodifiable()感兴趣。我把这个答案限制在ImmutableList上,但可以自由地问一个关于差异的新问题,我会回来写更多。我理解UnmodifiableMutableList(名称非常明确),但我想问的是为什么不让ImmutableList扩展列表,在add和remove上抛出UnsupportedOperationException,但是要保持列表及其包含的对象的不变性,你所描述的肯定会起作用。归根结底是设计上的权衡。UnsupportedOperationException令人费解,很难处理,尽管可以说它并不比上面的类图更令人费解。如果我们在ImmutableList上有变异方法,我们还可以将它们拉到父级ListIterable。然后,MutableList和ImmutableList将成为空的标记接口,这很奇怪。我们可以删除它们,但ListIterable.add()可能会抛出,也可能不会抛出。当前设计的缺点是互操作性。好处是能够清楚地表达意图,特别是对于字段。