This article introduces how to safely delete items during while iterating List.
While iterating the List using For Loop, if an item is deleted, an exception may occur or a problem may occur in which it is not possible to search for an item.
ConcurrentModificationException
If a specific item in ArrayList is deleted in the for loop as follows, ConcurrentModificationException may occur. When an item in the list is deleted during traversal, the Index of the next referenced item may be out of the range of the List, and an Exception occurs at this time.
The following code throws an Exception during traversal. This code has potential problems.
import java.util.ArrayList;
import java.util.List;
public class RemoveFromListIterating1 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("kiwi");
list.add("melon");
list.add("banana");
for (String item : list) {
if (item.equals("kiwi")) {
list.remove(item);
}
}
}
}
Output:
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at RemoveFromListIterating1.main(RemoveFromListIterating1.java:13)
Items missing during traversal
Even if ConcurrentModificationException does not occur, if an item is deleted while searching from a low index to a high index, some items may be excluded from the search.
If you run the code below, kiwi
was not found during list traversal. Therefore, this code also has potential problems.
List<String> list = new ArrayList<>();
list.add("apple");
list.add("kiwi");
list.add("melon");
list.add("banana");
for (int i = 0; i < list.size(); i++) {
String item = list.get(i);
System.out.println("Iterating: " + item);
if (item.equals("apple") || item.equals("kiwi")) {
list.remove(item);
}
}
System.out.println(list);
Output:
Iterating: apple
Iterating: melon
Iterating: banana
[kiwi, melon, banana]
1. Traversing the list from high index to low index
By traversing the list from high index to low index, you can safely delete items in a for loop. This is because deleting an item does not affect the Index of the next item to be searched for.
import java.util.ArrayList;
import java.util.List;
public class RemoveFromListIterating2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("kiwi");
list.add("melon");
list.add("banana");
for (int i = (list.size() - 1); i > -1; i--) {
String item = list.get(i);
System.out.println("Iterating: " + item);
if (item.equals("kiwi")) {
list.remove(item);
}
}
System.out.println("Result: " + list);
}
}
Output:
Iterating: banana
Iterating: melon
Iterating: kiwi
Iterating: apple
Result: [apple, melon, banana]
2. Search, then delete later
How to delete items using two for loops.
You can save the item to be deleted in the first Loop in another list and safely delete the item in the second Loop.
import java.util.ArrayList;
import java.util.List;
public class RemoveFromListIterating2_1 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("kiwi");
list.add("melon");
list.add("banana");
List<String> removed = new ArrayList<>();
for (String item : list) {
System.out.println("Iterating: " + item);
if (item.equals("kiwi")) {
removed.add(item);
}
}
for (String item : removed) {
list.remove(item);
}
System.out.println("Result: " + list);
}
}
Output:
Iterating: apple
Iterating: kiwi
Iterating: melon
Iterating: banana
Result: [apple, melon, banana]
3. Collection.removeIf()
Collection.removeIf()
passes the functional interface Predicate as an argument, and safely deletes items that meet the condition.
import java.util.ArrayList;
import java.util.List;
public class RemoveFromListIterating3 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("kiwi");
list.add("melon");
list.add("banana");
list.removeIf(item -> item.equals("kiwi"));
System.out.println("Result: " + list);
}
}
Output:
Result: [apple, melon, banana]
4. Iterator
An Iterator can be used to traverse a list and safely delete specific items.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class RemoveFromListIterating4 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("apple");
list.add("kiwi");
list.add("melon");
list.add("banana");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String item = it.next();
System.out.println("Iterating: " + item);
if (item.equals("kiwi")) {
it.remove();
}
}
System.out.println("Result: " + list);
}
}
Output:
Iterating: apple
Iterating: kiwi
Iterating: melon
Iterating: banana
Result: [apple, melon, banana]
Related Posts
- Java - Remove items from List while iterating
- Java - How to find key by value in HashMap
- Java - Update the value of a key in HashMap
- Java - How to put quotes in a string
- Java - How to put a comma (,) after every 3 digits
- BiConsumer example in Java 8
- Java 8 - Consumer example
- Java 8 - BinaryOperator example
- Java 8 - BiPredicate Example
- Java 8 - Predicate example
- Java 8 - Convert Stream to List
- Java 8 - BiFunction example
- Java 8 - Function example
- Java - Convert List to Map
- Exception testing in JUnit
- Hamcrest Collections Matcher
- Hamcrest equalTo () Matcher
- AAA pattern of unit test (Arrange/Act/Assert)
- Hamcrest Text Matcher
- Hamcrest Custom Matcher
- Why Junit uses Hamcrest
- Java - ForkJoinPool
- Java - How to use Futures
- Java - Simple HashTable implementation
- Java - Create a file in a specific path
- Java - Mockito의 @Mock, @Spy, @Captor, @InjectMocks
- Java - How to write test code using Mockito
- Java - Synchronized block
- Java - How to decompile a ".class" file into a Java file (jd-cli decompiler)
- Java - How to generate a random number
- Java - Calculate powers, Math.pow()
- Java - Calculate the square root, Math.sqrt()
- Java - How to compare String (==, equals, compare)
- Java - Calculate String Length
- Java - case conversion & comparison insensitive (toUpperCase, toLowerCase, equalsIgnoreCase)