43

Possible Duplicate:
Java: adding elements to a collection during iteration

My problem is that I want to expand a list with new elements while iterating over it and I want the iterator to continue with the elements that I just added.

From my understanding the ListIterator.add() adds an element before the current element in the list, not after it. Is it possible to achieve this in some other way?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
adamfinstorp
  • 1,627
  • 3
  • 17
  • 26
  • You can use ListLterator for modifying list during iterating,it provides more functionality than iterator. – Akash5288 Jan 26 '14 at 19:31

3 Answers3

44

You can't modify a Collection while iterating over it using an Iterator, except for Iterator.remove().

However, if you use the listIterator() method, which returns a ListIterator, and iterate over that you have more options to modify. From the javadoc for add():

The new element is inserted before the implicit cursor: ... a subsequent call to previous() would return the new element

Given that, this code should work to set the new element as the next in the iteration:

ListIterator<T> i;
i.add(e);
i.previous(); // returns e
i.previous(); // returns element before e, and e will be next

This will work except when the list starts iteration empty, in which case there will be no previous element. If that's a problem, you'll have to maintain a flag of some sort to indicate this edge case.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
14

There might be some trick with ListIterator, but the easiest solution is probably an old style index loop. Verify performance isn't an issue (no linked lists - but ArrayList is fine).

List<Object> myList;

for(int i = 0; i < myList.size(); i++)
{
  Object current = myList.get(i); 
  // Anything you insert after i will be discovered during next iterations
}
ptyx
  • 4,074
  • 1
  • 19
  • 21
  • 1
    Yep. This not only solves the problem unambiguously, but avoids the gotchas of not knowing how an iterator is going to act. I like it! – Chuck Glenn Nov 17 '14 at 15:02
  • hmm. if you add a element into list here, you get infinity loop: myList.add(current + "one more"); – yaroslavTir Dec 23 '14 at 19:28
  • 1
    @yaroslavTir yes? Obviously you need to make sure there is an end condition (like with any recursive code or queue processing). – ptyx Dec 23 '14 at 22:13
  • 1
    Isn't it O(n^2)? As we have a loop (O(n)) and inside of it we also retrieving element from any position (also O(n)) – Anton Feb 02 '18 at 08:39
  • @Anton absolutely. On your average list where n is < 100 (or even 1000), it probably won't matter and getting simpler easier to read code is a better solution than convoluted optimized code. (Or not, it depends - but premature optimization is the root of all evil) – ptyx Feb 02 '18 at 16:51
9

How about

List<Foo> fooList = getFooList();
List<Foo> tempFooList = new ArrayList<Foo>()


for(Foo f : fooList)
{
   ...
   // add items that need to be added to temp
   tempFooList.add(new Foo());
   ...
}

fooList.addAll(tempFooList);
Bala R
  • 107,317
  • 23
  • 199
  • 210