37

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?

0

7 Answers 7

52

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.

Sign up to request clarification or add additional context in comments.

Comments

10

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?

Comments

8

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
}

2 Comments

No, it won't. It will when using an iterator and adding alements while iterating, but not when doing iteration on your own here.
OPs wants "to iterate up to the intial size".
3

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.

Comments

1

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.

Comments

0

To help with this I created a function to make this more easy to achieve it.

public static <T> void forEachCurrent(List<T> list, Consumer<T> action) {
    final int size = list.size();
    for (int i = 0; i < size; i++) {
        action.accept(list.get(i));
    }
}

Example

    List<String> l = new ArrayList<>();
    l.add("1");
    l.add("2");
    l.add("3");
    forEachCurrent(l, e -> {
        l.add(e + "A");
        l.add(e + "B");
        l.add(e + "C");
    });
    l.forEach(System.out::println);

Comments

0

We can store the integer value while iterating in the list using for loop.

import java.util.*;

class ArrayListDemo{
    public static void main(String args[]){
      Scanner scanner = new Scanner(System.in);
      List<Integer> list = new ArrayList<Integer>();
      System.out.println("Enter the number of elements you wanna print :");
      int n = scanner.nextInt();
      
      System.out.println("Enter the elements :");
      for(int i = 0; i < n; i++){
          list.add(scanner.nextInt());
      }
      
      System.out.println("List's elements are : " + list);
      
      /*Like this you can store string while iterating in java using forloop*/

      List<String> list1 = new ArrayList<String>();
      System.out.println("Enter the number of elements you wanna store or print : ");
      int nString = scanner.nextInt();
      System.out.println("Enter the elements : ");
      for(int i = 0; i < nString; i++){
          list1.add(scanner.next());
      }
      System.out.println("Names are : " + list1);
      scanner.close();
   }
 }
   

Output:

Enter the number of elements you wanna print : 
5 
Enter the elements : 
11 
12 
13 
14 
15 
List's elements are : [11, 12, 13, 14, 15] 
Enter the number of elements you wanna store or print : 
5 
Enter the elements : 
apple 
banana 
mango 
papaya
orange 
Names are : [apple, banana, mango, papaya, orange] 

1 Comment

In the future, if the output can be copied, please paste in the output as a code block. Leave screenshots for visual problems that cannot be easily conveyed in words

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.