例如,假设有一个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)
}
是否应该有一些实现会从ConcurrentModificationException
中抛出ListIterator#set
?或者,是否存在应该引起异常抛出的 specific 修改类型(即“结构”)?是否暗示List
的某些实现可以合理地引发上述操作的异常?
答案 0 :(得分:5)
是否应该有一些实现会从
ConcurrentModificationException
中抛出ListIterator::set
?
答案是可能存在 。
List
,ListIterator
和ConcurrentModificationException
的Javadocs会不加修饰地说明允许和不允许的修改条款详细介绍允许的内容。如果查看(例如)ArrayList
的javadocs,您会发现它表明在迭代过程中允许不引起结构修改的更改。但是,这并不适用于所有列表类型。例如在CopyOnWriteArrayList
的迭代过程中允许进行所有修改。
自定义列表类型可以对修改施加不同的约束。
或者,是否存在应该引起异常抛出的特定类型的修改(即“结构化”)?
ListIterator::set
不是结构修改。但是对于某些列表类,在迭代过程中进行“结构”修改将导致CME。
其他(假设的)示例:
可以实现一个自定义列表类 ,如果(例如)两个迭代器处于活动状态,则不允许set
操作,如果发生则抛出CME。
在作为其他列表排序视图的自定义列表中,违反顺序的set
调用可能会引发CME。
这些可能可能是不同的例外;例如UnsupportedOperationException
。我对javadocs的理解是CME 将是合适的。
是否暗示
List
的某些实现可能合理地引发上述操作的异常?
是的。自定义List
实现只要符合List
和Collection
API中定义的行为,就可以完成各种“有趣”的事情。
问:您是否需要在代码中允许这样做?
A:IMO编写您的代码是合理的,这样它就可以用于“正常”列表。不可能允许自定义列表类可能做的所有疯狂的事情。