2013-06-01 2 views
1

У меня есть небольшая проблема с ListIterator.Как изменить subList без ConcurrentModificationException?

Я начал повторять исходный список [1, 4, 5], я между 1 и 4. Затем я меняю список на [1, 2, 3, 4, 5]. Теперь я хотел бы повторить оставшийся исходный список. Здесь я привожу пример кода:

public class Test { 
    public static void main(String[] args) {   
     List<Integer> list = new LinkedList<Integer>(); // [] 
     list.add(new Integer(1)); // [1] 
     list.add(new Integer(4)); // [1, 4] 
     list.add(new Integer(5)); // [1, 4, 5] 
     ListIterator<Integer> iterator = (ListIterator<Integer>) list.iterator(); 

     System.out.println(iterator.next()); // prints [1] 

     // modify subList 
     List<Integer> subList = list.subList(0, 2); // [1, 4] 
     subList.add(1, new Integer(2)); // [1, 2, 4] 
     subList.add(2, new Integer(3)); // [1, 2, 3, 4] 

     // need to print rest of oryginal list: [4, 5] 
     while (iterator.hasNext()) 
      System.out.println(iterator.next()); 
    } 
} 

Когда я его выполнения у меня java.util.ConcurrentModificationException. Вы знаете, как я могу это сделать правильно?

+2

Вы не можете изменить что-то в то время как вы итерацию над ним. Вам нужно будет сделать копию, чтобы изменить и перебрать оригинал. – Colleen

ответ

0

Если вы сделаете изменения в список с помощью итератора (а не через список), то вы не получите ConcurrentModificationException

System.out.println(iterator.next()); // prints [1] 

    iterator.add(new Integer(2)); // [1, 2, 4] 
    iterator.add(new Integer(3)); // [1, 2, 3, 4] 

    while (iterator.hasNext()) 
     System.out.println(iterator.next()); 
+0

2 и 3 будут пропущены автоматически. Из документов о [ListIterator # add] (http://docs.oracle.com/javase/7/docs/api/java/util/ListIterator.html#add (E)): «Новый элемент вставлен перед неявный курсор: последующий вызов следующего не будет затронут, а последующий вызов предыдущего вернет новый элемент ». –

+0

Когда я изменяю subList, у меня нет доступа к исходному итератору. – WojciechKo

+0

@WojciechKo В этом случае другой вариант заключается в использовании [CopyOnWriteArrayList] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html) - он возвращает итераторы при моментальных снимках , поэтому они никогда не будут бросать «ConcurrentModificationExceptions». Другой вариант - использовать [ConcurrentLinkedQueue] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html) - его итераторы слабо согласованы и никогда не будут бросать ' ConcurrentModificationExceptions' –

5

Вы неправильно поняли использование list.subList.

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

То, что вы хотите, чтобы скопировать часть исходного списка:

List<Integer> subList = new ArrayList<Integer>(list.subList(0,2)); 
Смежные вопросы