Remove multiple items from ArrayList during iterator

Thommy :

Is it safe to remove multiple items from an ArrayList while iterating through it with an iterator?

Iterator<String> iterator = nameList.iterator();
 while(iterator.hasNext()){
     String s = iterator.next();
     List<String> list = work(s);
     for (String s1 : list) {
        nameList.remove(s1);   
    }
}

The work() method gives back a list of names that should be removed from the nameList, during the runtime of while loop.

Eran :

No, it's not safe, and can throw ConcurrentModificationException. You can collect all the elements to be removed in a temporary List, and then call list.removeAll(tmpList) after the while loop to perform the removal.

Iterator<String> iterator = nameList.iterator();
List<String> removed = new ArrayList<>();
while(iterator.hasNext()){
    String s = iterator.next();
    removed.addAll(work(s));
}
list.removeAll(removed);

I realize this can be less efficient, since you might be calling work(s) on Strings the should have been removed from the List earlier. This can be improved by changing tempList to a Set, and only calling work(s) for Strings not in the Set:

Iterator<String> iterator = nameList.iterator();
Set<String> removed = new HashSet<>();
while(iterator.hasNext()){
    String s = iterator.next();
    if (!removed.contains(s)) {
        removed.addAll(work(s));
    }
}
list.removeAll(removed);

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=472033&siteId=1