Remove list of elements before iterating in java

Viewed 58

I have a String List.On a satisfied Condition ,I need to group strings and remove those before iterating. For example;

List<String> test = new ArrayList();
List<String> newLst = new ArrayList();
test.add("A1");
test.add("A2");
test.add("A3");
test.add("A1B1");
test.add("C1");
for(String s: test){
    if(s.startsWith("A"){
        newLst.add(s);
        test.remove(s);
    }
}

Once A1 reaches the loop,collect related string in new list and remove it from existing.

Getting Concurrent Modification exception.Kindly help to solve this.

Output: newLst: A1,A2,A3 test : A1B1,C1

newLst : A1B1 test:C1

newLst : C1

3 Answers

You could use an explicit Iterator to iterate over the List, and use that Iterator's remove() method inside the loop (instead of List's remove()), but it would be simpler to remove from test all the elements added to newLst after the loop:

for(String s: test){
    if(s.startsWith("A"){
        newLst.add(s);
    }
}
test.removeAll(newLst);

You can filter out elements starting with A using stream:

List<String> result = test.stream()
            .filter(line -> line.startsWith("A")) 
            .collect(Collectors.toList()); 
result.forEach(System.out::println);  //This is for printing elements

Why you are getting ConcurrentModificationException ?

That's because you are trying to modify the collection while iterating over it's items. The only safe way to modify your collection during iteration Iterator.remove(); The same applies for Iterator.add() (Whether you delete or add an item it counts as a modification).

JDK < 8 SOLUTION

List<String> sourceList = new ArrayList();
List<String> destList = new ArrayList();
sourceList.add("A1");
sourceList.add("A2");
sourceList.add("A3");
sourceList.add("A1B1");
sourceList.add("C1");
Iterator<String> iterator = sourceList.iterator();

while (iterator.hasNext()) {
    String s = iterator.next();
    if(s.startsWith("A"){
        destList.add(s);
        iterator.remove(s);
    }
}

JDK > 8 SOLUTION

List<String> destList = sourceList.stream()
      .filter(item -> item.startsWith("A")) 
      .collect(Collectors.toList());

Note that Java streams use Spliterator which quite different than an Iterator.

A stream source is described by an abstraction called Spliterator. As its name suggests, Spliterator combines two behaviors: accessing the elements of the source (iterating), and possibly decomposing the input source for parallel execution (splitting).

For further details , i advise you to check this interesting post about how streams works under the hood

Related