-1

I am removing elements from a list in one loop and this list is being iterated in another loop. ConcurrentModificationException was expected. Is there a work around to solve this? The point is I already have a loop and based on certain conditions I have to reduce its size and after modification it should iterate according to new size of the list. The list modification is happening in another loop.

static List<String> list = new ArrayList<>();

private static void initilizeList() {
    for(int i = 0; i < 10; i++){
        list.add(String.valueOf(i));
    }
}

private static void iterateList() {
    for(String s: list){
        System.out.println(s);
        if(s.equals("5")){
            modifyList();
        }
    }
}

private static void modifyList() {
    for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
        String element = iterator.next();
        if (element.equalsIgnoreCase("5")) {
            break;
        }
        iterator.remove();
    }
}
Tishy Tash
  • 357
  • 2
  • 12
  • 1
    Does this answer your question? [Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop](https://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re) – Amongalen Jan 17 '20 at 14:41
  • You modify the list while inside the outer loop. Doesn't matter that there is another loop inside. – Amongalen Jan 17 '20 at 14:44

1 Answers1

0

An iterator will always continue iterating according to the new size of the list if you use the iterator to remove elements. It will not start over, but it will stop with the last element of the list.

I'm a bit puzzled by your loop in modifyList(). You're iterating in a for loop over the iterator of the list. If your aim is just to remove the element "5", then I'd go with this:

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

public class Iterating {

  static List<String> list = new ArrayList<>();

  private static void initilizeList() {
      for(int i = 0; i < 10; i++){
          list.add(String.valueOf(i));
      }
  }

  private static void modifyList() {
    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
        String element = iterator.next();
        if (element.equalsIgnoreCase("5")) {
            iterator.remove();
        }
    }
  }

  public static void main(String[] args) {
    initilizeList();
    System.out.println("Before: " + list);
    modifyList();
    System.out.println("After: " + list);
  }
}

Output:

Before: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
After: [0, 1, 2, 3, 4, 6, 7, 8, 9]

If your aim is to remove all elements up until "5", you can use methods on List:

  private static void reduceList() {
    int i = list.indexOf("5");
    if (i > -1)
      list = new ArrayList<String>(list.subList(i, list.size()));
  }

Output:

Before: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
After: [5, 6, 7, 8, 9]
Scratte
  • 3,056
  • 6
  • 19
  • 26