Advertisement
Advertisement


How to add element in List while iterating in java?


Question

Say I have a List like:

List<String> list = new ArrayList<>();
list.add("a");
list.add("h");
list.add("f");
list.add("s");

While iterating through this list I want to add an element at the end of the list. But I don't want to iterate through the newly added elements that is I want to iterate up to the initial size of the list.

for (String s : list)
     /* Here I want to add new element if needed while iterating */

Can anybody suggest me how can I do this?

2012/06/24
1
32
6/24/2012 12:13:48 PM

Accepted Answer

You can't use a foreach statement for that. The foreach is using internally an iterator:

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.

(From ArrayList javadoc)

In the foreach statement you don't have access to the iterator's add method and in any case that's still not the type of add that you want because it does not append at the end. You'll need to traverse the list manually:

int listSize = list.size();
for(int i = 0; i < listSize; ++i)
  list.add("whatever");

Note that this is only efficient for Lists that allow random access. You can check for this feature by checking whether the list implements the RandomAccess marker interface. An ArrayList has random access. A linked list does not.

2012/06/24
46
6/24/2012 12:21:20 PM

Iterate through a copy of the list and add new elements to the original list.

for (String s : new ArrayList<String>(list))     
{
    list.add("u");
}

See How to make a copy of ArrayList object which is type of List?

2017/05/23

Just iterate the old-fashion way, because you need explicit index handling:

List myList = ...
...
int length = myList.size();
for(int i = 0; i < length; i++) {
   String s = myList.get(i);
   // add items here, if you want to
}
2012/06/24

You could iterate on a copy (clone) of your original list:

List<String> copy = new ArrayList<String>(list);
for (String s : copy) {
    // And if you have to add an element to the list, add it to the original one:
    list.add("some element");
}

Note that it is not even possible to add a new element to a list while iterating on it, because it will result in a ConcurrentModificationException.

2012/06/24

I do this by adding the elements to an new, empty tmp List, then adding the tmp list to the original list using addAll(). This prevents unnecessarily copying a large source list.

Imagine what happens when the OP's original list has a few million items in it; for a while you'll suck down twice the memory.

In addition to conserving resources, this technique also prevents us from having to resort to 80s-style for loops and using what are effectively array indexes which could be unattractive in some cases.

2012/06/24