在使用 ListIterator 时,我们何时(或何时不允许)允许并发修改?
When do we (or when do we not) allow concurrent modification when using ListIterator?
例如,假设有一些 Collections#reverse(List)
操作这样使用 ListIterator
:
var forwardItr = list.listIterator();
var reverseItr = list.listIterator(list.size());
while (forwardItr.nextIndex() < reverseItr.previousIndex()) {
var forward = forwardItr.next();
var reverse = reverseItr.previous();
forwardItr.set(reverse)
reverseItr.set(forward)
}
是否应该有一些实现从 ListIterator#set
中抛出 ConcurrentModificationException
?或者更确切地说,是否存在应该导致异常抛出的 特定 类型的修改(即 "structural")?是否暗示 List
的某些实现可能会合理地从上述操作中抛出异常?
Should there ever be some implementation that throws a ConcurrentModificationException
from ListIterator::set
?
答案是可能。
List
、ListIterator
和 ConcurrentModificationException
的 javadoc 讨论了 允许 和 不允许的修改条款permissible 而不是详细说明什么是允许的。如果您查看(比如)ArrayList
的 javadoc,您会看到它表示在迭代期间允许不导致结构修改的更改。但是,这并不适用于所有列表类型;例如在 CopyOnWriteArrayList
的迭代期间允许所有修改。
自定义列表类型可以对修改设置不同约束。
Or rather, is there a particular type of modification (i.e. "structural") that should cause an exception throw?
嗯ListIterator::set
不是结构修改。但是对于某些列表 classes,迭代期间的 "structural" 修改将导致 CME。
其他(假设的)示例:
自定义列表 class 可以 实现,如果(比如)两个迭代器处于活动状态,则不允许 set
操作,如果发生这种情况,请抛出 CME。
在作为其他内容的排序视图的自定义列表中,破坏排序的 set
调用可能会引发 CME。
有争议,这些可能是不同的例外;例如UnsupportedOperationException
。我对 javadoc 的阅读是 CME 会 是合适的。
Is it implied that some implementations of List
may justifiably throw an exception from the aforementioned operation?
是的。自定义 List
实现可以做各种 "interesting" 事情,只要它符合 List
和 Collection
API 中定义的行为。
问:您需要在代码中允许这样做吗?
答:IMO 编写您的代码使其适用于 "normal" 列表是合理的。不可能允许自定义列表 class 可能做的所有疯狂事情。
例如,假设有一些 Collections#reverse(List)
操作这样使用 ListIterator
:
var forwardItr = list.listIterator();
var reverseItr = list.listIterator(list.size());
while (forwardItr.nextIndex() < reverseItr.previousIndex()) {
var forward = forwardItr.next();
var reverse = reverseItr.previous();
forwardItr.set(reverse)
reverseItr.set(forward)
}
是否应该有一些实现从 ListIterator#set
中抛出 ConcurrentModificationException
?或者更确切地说,是否存在应该导致异常抛出的 特定 类型的修改(即 "structural")?是否暗示 List
的某些实现可能会合理地从上述操作中抛出异常?
Should there ever be some implementation that throws a
ConcurrentModificationException
fromListIterator::set
?
答案是可能。
List
、ListIterator
和 ConcurrentModificationException
的 javadoc 讨论了 允许 和 不允许的修改条款permissible 而不是详细说明什么是允许的。如果您查看(比如)ArrayList
的 javadoc,您会看到它表示在迭代期间允许不导致结构修改的更改。但是,这并不适用于所有列表类型;例如在 CopyOnWriteArrayList
的迭代期间允许所有修改。
自定义列表类型可以对修改设置不同约束。
Or rather, is there a particular type of modification (i.e. "structural") that should cause an exception throw?
嗯ListIterator::set
不是结构修改。但是对于某些列表 classes,迭代期间的 "structural" 修改将导致 CME。
其他(假设的)示例:
自定义列表 class 可以 实现,如果(比如)两个迭代器处于活动状态,则不允许
set
操作,如果发生这种情况,请抛出 CME。在作为其他内容的排序视图的自定义列表中,破坏排序的
set
调用可能会引发 CME。
有争议,这些可能是不同的例外;例如UnsupportedOperationException
。我对 javadoc 的阅读是 CME 会 是合适的。
Is it implied that some implementations of
List
may justifiably throw an exception from the aforementioned operation?
是的。自定义 List
实现可以做各种 "interesting" 事情,只要它符合 List
和 Collection
API 中定义的行为。
问:您需要在代码中允许这样做吗?
答:IMO 编写您的代码使其适用于 "normal" 列表是合理的。不可能允许自定义列表 class 可能做的所有疯狂事情。