Итерация ArrayList, где каждый элемент вызывается только один раз

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

Как это может быть сделано?

Спасибо вам всем.


person Aeon    schedule 15.05.2014    source источник
comment
Нет, новый вставленный элемент не будет повторяться. Как говорится в документе, новый элемент вставляется перед неявным курсором: последующий вызов next не будет затронут Пример: программа: List<Integer> list = new ArrayList<>(Arrays.asList(2,1)); ListIterator<Integer> ite = list.listIterator(); while(ite.hasNext()){ if(ite.next()%2 == 0){ite.add(4);}} правильно завершается и выводит [2,4,1].   -  person Alexis C.    schedule 15.05.2014
comment
Также вы можете добавить элементы во временный список, а затем добавить его в исходный список после цикла.   -  person Averroes    schedule 15.05.2014
comment
Возможно, CopyOnWriteArrayList?   -  person Totoro    schedule 15.05.2014


Ответы (2)


Это зависит от того, как вы хотите, чтобы результирующий список выглядел.

Если вы довольны тем, что новые элементы существуют среди элементов, которые были изначально, вы можете взять пример ZouZou и использовать методы ListIterator add() и remove().

final List<Integer> list = new ArrayList<Integer>(Arrays.asList(2,3,4,5,6));
final ListIterator<Integer> ite = list.listIterator();
while( ite.hasNext() ) {
    if( ite.next() %2 == 0 ) {
        ite.add( 7 );
    }
    else {
        ite.remove(); //removes the last value returned by next()
    }
}

Вывод:

список = [2, 7, 4, 7, 6, 7]

Однако, если вы хотите, чтобы все новые элементы располагались после исходных элементов, лучше всего использовать вторую коллекцию.

final List<Integer> list = new ArrayList<Integer>(Arrays.asList(2,3,4,5,6));
final List<Integer> newList = new ArrayList<Integer>(list);
final ListIterator<Integer> ite = list.listIterator();
while( ite.hasNext() ) {
    final Integer next = ite.next();
    if( next % 2 == 0 ) {
        newList.add( 7 );
    }
    else {
        newList.remove(next);
    }
}

Вывод:

новый список = [2, 4, 6, 7, 7, 7]

Лично я всегда был поклонником использования второго метода сбора, поскольку он позволяет избежать возможности ConcurrentModificationException при итерации по индексу.

person Dan Temple    schedule 15.05.2014

Метод set, вероятно, то, что вы ищете:

import java.util.*;

public class IterDemo {
    public static void main(String[] args) {
        List<String> arrayList = new ArrayList() {{
            add("one");
            add("two");
            add("three");
        }};

        System.out.println("Before: " + arrayList);

        ListIterator<String> iter = arrayList.listIterator();
        while(iter.hasNext()) {
            String s = iter.next();
            iter.set(s.toUpperCase());
        }

        System.out.println("After: " + arrayList);
    }
}
person Jeff Scott Brown    schedule 15.05.2014