11

假设我有一个List对象和该列表的迭代器

现在我对列表进行排序java.util.Collections.sort()

  • 迭代器会发生什么?
  • 它的行为是否仍然被定义并且仍然可以使用?
  • 如果没有,我可以防止破坏列表的迭代器吗?

我知道,这个问题可以通过改变程序设计来规避,例如克隆列表,但我特别想知道 Java 的“官方”行为。

4

4 回答 4

18

迭代器通常在对其基础集合进行任何修改后无效,除非通过迭代器本身。(例如,ListIterator允许插入和移除。)

我当然希望任何迭代器在排序后都会失效——如果不是,我不知道期望什么顺序。

于 2008-11-18T15:51:52.053 回答
16

中的大多数集合java.util都是“快速失败的”,如果基础集合发生更改,可能会抛出一个。ConcurrentModificationException应该指出的是,这是用于调试的,因此不能保证。根据 javadocs,对于 的所有后继者都是如此AbstractList,但对于旨在用于多线程使用的 而言,情况并非如此。CopyOnWriteArrayList

于 2008-11-18T15:55:14.463 回答
4

通常,集合上的任何类型的突变都会使其迭代器无效。通过迭代器完成的突变不会使该迭代器无效。有一些特殊的集合实现,例如CopyOnWriteArrayList.

一般的解决方案是对集合的副本进行排序或重新创建迭代器。

于 2008-11-18T15:55:10.080 回答
2

我编写了一些代码来查看在迭代时对集合进行排序时会发生什么。迭代器似乎没有抛出任何异常,而是继续正常迭代。如果您期望遍历未排序的集合,它仍然会给您错误的结果。看那个 :

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());
    }
    }

希望能帮助到你。

于 2008-11-18T16:13:14.617 回答