[英]Do the Guava Immutable* classes satisfy the standard collection interfaces they implement?
For instance, if I have an interface like 例如,如果我有一个类似的界面
public interface Partition<E> {
Set<E> getIncluded();
Set<E> getExcluded();
}
And I implement it like so 我这样实现它
public class ImmutablePartition<E> implements Partition<E> {
private final ImmutableSet<E> included;
private final ImmutableSet<E> excluded;
ImmutablePartition(Set<E> included, Set<E> excluded) {
this.included = ImmutableSet.copyOf(included);
this.excluded = ImmutableSet.copyOf(excluded);
}
@Override
public Set<E> getIncluded() {
return included;
}
@Override
public Set<E> getExcluded() {
return excluded;
}
}
Am I really implementing the spirit of the original interface? 我真的实现了原始界面的精神吗? If client code gets a
Set<E>
back, tries to manipulate it, and gets an UnsupportedOperationException
, surely that defeats the purpose of implementing the Set<E>
interface in the first place? 如果客户端代码返回
Set<E>
,尝试操作它,并获得UnsupportedOperationException
,这肯定会破坏首先实现Set<E>
接口的目的?
This question applies to all Guava Immutable* collections that implement the standard collection interfaces from java.util
. 此问题适用于实现
java.util
标准集合接口的所有Guava Immutable *集合。
edit: As I've been reminded below, the Collection
interface specifies the UnsupportedOperationException
for unsupported mutation methods. 编辑:正如我在下面提醒的那样,
Collection
接口为不支持的变异方法指定UnsupportedOperationException
。 I feel like the expectation still is that a returned collection will allow modification, unless otherwise stated. 除非另有说明,我觉得期望仍然是返回的集合将允许修改。 If I wanted to return an immutable collection, I would specify the return type as the immutable class, if possible.
如果我想返回一个不可变集合,我会将返回类型指定为不可变类,如果可能的话。
I guess my question is: being that the usual assumption (in my experience) is that a returned collection will be mutable, is it sensible to implement a interface method that returns a general collection and return an immutable collection? 我想我的问题是:通常的假设(根据我的经验)是返回的集合是可变的,实现一个返回一般集合并返回一个不可变集合的接口方法是否合理?
I don't know what the spirit of an interface is, but the specification (aka Javadoc ;-) of the Java collection interfaces clearly state that immutable collections may throw an UnsupportedOperationException
when the user tries to modify them. 我不知道接口的精神是什么,但Java集合接口的规范 (又名Javadoc ;-)清楚地表明,当用户尝试修改它们时,不可变集合可能会抛出
UnsupportedOperationException
。
Edit to also answer your edited question 编辑以回答您编辑的问题
First, I agree that whether a returned collection is mutable should be documented. 首先,我同意应该记录返回的集合是否可变。 However, I disagree that the default assumption is that the collection is mutable.
但是,我不同意默认的假设是该集合是可变的。 Also when a returned collection is mutable I expect that this is documented, and also that it is documented what happens when I modify the collection (in particular: is the object from which the collection originates modified when I modify the collection, or is it just a copy of some data).
此外,当返回的集合是可变的时,我希望这是记录的,并且还记录了当我修改集合时会发生什么(特别是:当我修改集合时,集合来自哪个对象,或者它只是一些数据的副本)。
It would maybe be good to have types like ImmutableSet
, ImmutableList
, and so on, but the Java standard library doesn't have them. 拥有像
ImmutableSet
, ImmutableList
等类型可能会很好,但Java标准库没有它们。 The reason is that the situation is not a boolean: a collection can be partially modifiable, for example because it allows deleting elements but not adding new ones. 原因是情况不是布尔值:集合可以是部分可修改的,例如因为它允许删除元素但不允许添加新元素。 It would not be a good idea to have seperate interfaces for all possible combinations, and therefore the Java designers decided to have none.
为所有可能的组合设置单独的接口并不是一个好主意,因此Java设计者决定不使用任何接口。
You can use an external library, such as Guava, but this also has disadvantages: 您可以使用外部库,例如Guava,但这也有缺点:
Do the Guava Immutable* classes satisfy the standard collection interfaces they implement?
YES . 是的
Behavior of interface method invocation is implementation specific, until explicitly restricted by documentation. 接口方法调用的行为是特定于实现的,直到文档明确限制。 Throwing
UnsupportedOperationException
is not violation of interface contract. 抛出
UnsupportedOperationException
不违反接口契约。
Example : 示例:
java.util.Collections.UnmodifiableList
, which implements java.util.List
do following: java.util.Collections.UnmodifiableList
,它实现了java.util.List
,如下所示:
public void remove() {
throw new UnsupportedOperationException();
}
public void set(E e) {
throw new UnsupportedOperationException();
}
public void add(E e) {
throw new UnsupportedOperationException();
}
If you check javadoc of particular methods of List
interface eg, boolean add(E e)
you can find following: 如果检查
List
接口的特定方法的javadoc,例如boolean add(E e)
您可以找到以下内容:
throws UnsupportedOperationException if the add operation is not supported by this list
Arrays.asList()
already returns List that does not permit add()
. Arrays.asList()
已经返回不允许add()
List。
So I guess returning non-modifiable or partially-modifiable collections are OK, judging that Java spirit is defined by Java standard library specification. 所以我认为返回不可修改或部分可修改的集合是可以的,判断Java精神是由Java标准库规范定义的。
It's perfectly valid (and in my view, preferable) to use ImmutableSet as the return type. 使用ImmutableSet作为返回类型是完全有效的(在我看来,更好)。 That clues in human readers that what they're getting will be immutable.
人类读者的线索是,他们所得到的将是不可改变的。
In my opinion it doesn't. 在我看来,它没有。 I know that the documentation states that there are optional operations, and even these methods may throw
UnsupportedOperationException
(which is an unchecked one so the caller might not be prepared for catching it), but I think the purpose of an interface is specifying of what can be done with an implementation, and since those methods are present on the interface, they should be properly implemented. 我知道文档声明有可选操作,甚至这些方法也可能抛出
UnsupportedOperationException
(这是一个未经检查的,因此调用者可能没有准备好捕获它),但我认为接口的目的是指定什么可以完成一个实现,并且由于这些方法存在于接口上,因此应该正确实现它们。 If there are optional operations then there should be some API to discover it by code, not by reading the documentations. 如果有可选操作,则应该有一些API通过代码发现它,而不是通过阅读文档。
I even think that throwing an UnsupportedOperationException
is violating the Liskov substitution principle . 我甚至认为抛出
UnsupportedOperationException
违反了Liskov替换原则 。 Make no mistake, I don't criticize Guava here, this is rather a problem with the standard Java collection framework, the authors of Guava wanted to seamlessly integrate the immutable collections into it and they had to make some compromise. 毫无疑问,我不批评Guava,这是标准Java集合框架的一个问题,Guava的作者希望将不可变集合无缝集成到它中,并且他们必须做出一些妥协。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.