假设我有一个List
对象和该列表的迭代器。
现在我对列表进行排序java.util.Collections.sort()
- 迭代器会发生什么?
- 它的行为是否仍然被定义并且仍然可以使用?
- 如果没有,我可以防止破坏列表的迭代器吗?
我知道,这个问题可以通过改变程序设计来规避,例如克隆列表,但我特别想知道 Java 的“官方”行为。
假设我有一个List
对象和该列表的迭代器。
现在我对列表进行排序java.util.Collections.sort()
我知道,这个问题可以通过改变程序设计来规避,例如克隆列表,但我特别想知道 Java 的“官方”行为。
迭代器通常在对其基础集合进行任何修改后无效,除非通过迭代器本身。(例如,ListIterator
允许插入和移除。)
我当然希望任何迭代器在排序后都会失效——如果不是,我不知道期望什么顺序。
中的大多数集合java.util
都是“快速失败的”,如果基础集合发生更改,可能会抛出一个。ConcurrentModificationException
应该指出的是,这是用于调试的,因此不能保证。根据 javadocs,对于 的所有后继者都是如此AbstractList
,但对于旨在用于多线程使用的 而言,情况并非如此。CopyOnWriteArrayList
通常,集合上的任何类型的突变都会使其迭代器无效。通过迭代器完成的突变不会使该迭代器无效。有一些特殊的集合实现,例如CopyOnWriteArrayList
.
一般的解决方案是对集合的副本进行排序或重新创建迭代器。
我编写了一些代码来查看在迭代时对集合进行排序时会发生什么。迭代器似乎没有抛出任何异常,而是继续正常迭代。如果您期望遍历未排序的集合,它仍然会给您错误的结果。看那个 :
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("D");
list.add("B");
list.add("A");
list.add("C");
list.add("E");
Iterator<String> it = list.iterator();
String s = it.next();
System.out.println(s);
s = it.next();
System.out.println(s);
Collections.sort(list);
Iterator<String> it2 = list.iterator();
s = it.next();
System.out.println(s);
s = it.next();
System.out.println(s);
s = it.next();
System.out.println(s);
while (it2.hasNext()) {
System.out.println(it2.next());
}
}
希望能帮助到你。