2008-11-18 2 views
9

Предположим, у меня есть a List объект и итератор для этого списка.Когда я сортирую список, что происходит с его итераторами?

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

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

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

ответ

15

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

17

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

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

+0

Это однозначный ответ для одного итератора `p`, указывающего на коллекцию` c`. Как насчет того, чтобы два итератора `p` и` q` указывали на одну и ту же коллекцию `c` и выполнялись независимо? Действительно ли _ «кроме самого итератора» означает конкретный экземпляр итератора, например `p`, или это означает любой экземпляр итератора? Я предполагаю, что независимая итерация `p` и` q` приведет к недействительности друг друга (просто потому, что нитераторы не знают о других итераторах, ни коллекция не запоминает всех своих итераторов), но это хорошо, чтобы прояснить ее здесь. Благодаря! – uvsmtid 2016-12-02 02:43:56

+1

@uvsmtid: Это только через этот конкретный итератор. Если у вас есть два итератора над одной и той же коллекцией, вы не можете изменять коллекцию с помощью любого из них, если только это не коллекция, которая явно поддерживает одновременную модификацию. – 2016-12-02 06:30:42

4

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

Общее решение - сортировать копию коллекции или воссоздавать итераторы.

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^