Когда я сортирую список, что происходит с его итераторами? - PullRequest
10 голосов
/ 18 ноября 2008

Допустим, у меня есть a List объект и итератор для этого списка.

Теперь я сортирую список с java.util.Collections.sort()

  • Что происходит с итератором?
  • Его поведение все еще определено и может ли оно все еще использоваться?
  • Если нет, могу ли я предотвратить уничтожение итераторов для списка?

Я знаю, что эту проблему можно обойти, изменив дизайн программы, например, клонировав список, но я специально хочу знать "официальное" поведение Java.

Ответы [ 4 ]

18 голосов
/ 18 ноября 2008

Итераторы, как правило, недействительны после любых изменений в их базовых коллекциях, кроме как через сам итератор. (Например, ListIterator допускает вставку и удаление.)

Я бы, конечно, ожидал, что любые итераторы станут недействительными после сортировки - и если бы их не было, я бы не знал, какой порядок ожидать.

16 голосов
/ 18 ноября 2008

Большинство коллекций в java.util являются «отказоустойчивыми», и может выдавать ConcurrentModificationException, если базовая коллекция изменяется. Следует отметить, что это предназначено для отладки и поэтому не гарантируется. Согласно Javadocs, это верно для всех потомков AbstractList, но это не верно для CopyOnWriteArrayList, который предназначен для нескольких резьбовое использование.

4 голосов
/ 18 ноября 2008

Как правило, любая мутация в коллекции делает недействительными ее итераторы. Мутация, выполненная с помощью итератора, не сделает этого итератора недействительным. Есть несколько исключительных реализаций коллекции, таких как CopyOnWriteArrayList.

Общим решением будет сортировка копии коллекции или воссоздание ваших итераторов.

2 голосов
/ 18 ноября 2008

Я написал некоторый код, чтобы увидеть, что происходит, когда коллекция сортируется во время итерации. Кажется, что итератор не выдает никаких исключений, но продолжает выполнять итерацию в обычном режиме. Тем не менее, он дает вам неправильные результаты, если вы ожидаете перебрать несортированную коллекцию. Посмотрите на это:

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

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...