Java 当我对列表排序时,它的迭代器会发生什么变化?
假设我有一个列表对象和一个该列表的迭代器 现在,我使用Java 当我对列表排序时,它的迭代器会发生什么变化?,java,collections,concurrency,Java,Collections,Concurrency,假设我有一个列表对象和一个该列表的迭代器 现在,我使用java.util.Collections.sort()对列表进行排序 迭代器会发生什么情况 其行为是否仍有定义,是否仍可以使用 如果没有,我可以防止销毁列表的迭代器吗 我知道,通过改变程序设计,例如克隆列表,可以避免这个问题,但我特别想知道Java的“官方”行为。迭代器在对其基础集合进行任何修改后通常无效,除非通过迭代器本身。(例如,允许插入和删除。) 不过,我当然希望任何迭代器在排序后都会失效——如果不是,我也不知道会出现什么顺序。通
java.util.Collections.sort()对列表进行排序
- 迭代器会发生什么情况李>
- 其行为是否仍有定义,是否仍可以使用李>
- 如果没有,我可以防止销毁列表的迭代器吗
我知道,通过改变程序设计,例如克隆列表,可以避免这个问题,但我特别想知道Java的“官方”行为。迭代器在对其基础集合进行任何修改后通常无效,除非通过迭代器本身。(例如,允许插入和删除。)
不过,我当然希望任何迭代器在排序后都会失效——如果不是,我也不知道会出现什么顺序。通常,集合上的任何类型的变异都会使其迭代器失效。通过迭代器进行的变异不会使迭代器失效。有一些特殊的集合实现,例如CopyOnWriteArrayList
一般的解决方案是对集合的副本进行排序或重新创建迭代器。java.util
中的大多数集合都是“快速失败的”,如果基础集合发生更改,可能会抛出一个错误。应该指出的是,这是为了调试,因此不能保证。根据javadocs,这适用于的所有死者,但这不适用于,它是用于多线程使用的 我编写了一些代码,以查看在迭代过程中对集合进行排序时会发生什么。迭代器似乎没有抛出任何异常,而是继续正常地进行迭代。但是,如果您希望在未排序的集合上进行迭代,那么它会给出错误的结果。看看这个:
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());
}
}
publicstaticvoidmain(字符串[]args){
列表=新的ArrayList();
列表。添加(“D”);
列表。添加(“B”);
列表。添加(“A”);
列表。添加(“C”);
列表。添加(“E”);
Iterator it=list.Iterator();
字符串s=it.next();
系统输出打印项次;
s=it.next();
系统输出打印项次;
集合。排序(列表);
迭代器it2=list.Iterator();
s=it.next();
系统输出打印项次;
s=it.next();
系统输出打印项次;
s=it.next();
系统输出打印项次;
while(it2.hasNext()){
System.out.println(it2.next());
}
}
希望有帮助。其中“正常”包括“可能再次看到相同的元素”。。。老实说,我有点失望,这没有引发异常。异常不一定会引发,它是用于调试的。对于指向集合
c
的单个迭代器p
来说,这是一个明确的答案。让两个迭代器p
和q
指向同一个集合c
并独立迭代怎么样?“除了通过迭代器本身”是指迭代器的特定实例,比如p
,还是指迭代器的任何实例?我猜p
和q
的独立迭代将使彼此无效(这仅仅是因为迭代器不知道其他迭代器,集合也不记得所有迭代器),但最好在这里澄清一下。谢谢@uvsmtid:除了通过特定的迭代器。如果在同一个集合上有两个迭代器,则不能通过它们中的任何一个修改集合,除非该集合明确支持并发修改。