在迭代该集合时,将元素添加到可修改的SortedSet
是否安全?特别是,将元素添加到集合中的元素是否比迭代器指示的元素更安全?
例如,以下代码是否会损坏SortedSet s
或抛出异常(可能是ConcurrentModificationException
):
/**
* s not null, is modifiable.
*/
private final addSelectedFollowers(final SortedSet<Integer> s)
{
for (Integer i: s) {
if (shouldAddNext(i)) {
s.add(i + 1);
}
}
}
protected abstract boolean shouldAddNext(int i);
我的猜测是 安全,但我在JRE API文档中找不到明确的声明。我知道如果没有指定行为,实现可以自由决定行为。在SortedSet
的文档中缺乏明确的陈述是不够的以这种或那种方式回答问题;可以在不同类或接口的文档中间接指定所需行为。遗憾的是,JRE记录员并不总是明确说明允许的内容。因此,我正在寻找引用JRE API的答案,而不是是或 no 的光头断言。我也知道可以SortedSet
SortedSet.add()
,这会使SortedSet
失败;我对可修改a(k,l)
。
请注意,我要求在集合中添加元素,而不是unmodifiable。
答案 0 :(得分:6)
这取决于实施。例如,在TreeSet
的情况下,迭代器是故障快速,因此在迭代时添加元素将触发ConcurrentModificationException
。
来自TreeSet
的JavaDoc:
此类的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时间修改集合,除了通过迭代器自己的删除方法之外,迭代器将抛出ConcurrentModificationException。因此,面对并发修改,迭代器会快速而干净地失败,而不是在未来不确定的时间冒着任意的,非确定性行为的风险。
使用非故障快速迭代器的其他实现可能允许在迭代时添加元素。
答案 1 :(得分:5)
如果未指定行为,则实现可以自由决定行为。
例如,Javadoc中列为已知实现类的两个类实现了两种行为:
迭代器是弱一致的,在迭代器创建时或之后的某个时刻返回反映集合状态的元素。 它们不会抛出ConcurrentModificationException ,并且可能会与其他操作同时进行。
此类的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时间修改了set,除了通过迭代器自己的remove方法之外,迭代器将抛出ConcurrentModificationException 强>
但是,更基本的是,Collection.add
(和Set.add
)被记录为可选操作,因此我们永远不会依赖对SortedSet.add
的调用无论是否在正在进行的迭代中,都是安全的。
例如,在Collections.unmodifiableSortedSet
或Guava ImmutableSortedSet
返回的add
上调用SortedSet
会产生UnsupportedOperationException
。