Preface
In Java development,Delete elements during collection traversalIt is a common but error-prone operation. Different collection types (such asArrayList
、 HashSet
) There are different ways to deal with it, and incorrect use may lead toConcurrentModificationException
abnormal. This article will comprehensively analyze the root causes of this problem, provide best practices, compare different methods, and demonstrate specific implementation through case demonstration.
1. Problem background
In Java, collections areList
andSet
Data structures such as the ones are often used to store elements. Deleting elements while traversing these collections can cause problems, such as:
-
ConcurrentModificationException: Through regular
for-each
oriterator
Called directly during traversalremove()
Methods will raise this exception because the internal structure of the collection is modified during traversal. - Iterator failed: The iterator fails because the iterator and the collection share the internal structure, modifying the collection elements.
To deal with this problem, Java provides several different solutions.
2. Comparison of different solutions
method | Is it safe to delete | Will exceptions be thrown | efficiency | Can you traverse other collections |
---|---|---|---|---|
use()
|
Safety | Don't throw exceptions | High efficiency | Supports multiple collections |
for-each + Manually delete |
Insecure | Will throw exceptions | Inefficient | Applicable onlyList
|
for Loop reverse traversal |
Safety | Don't throw exceptions | generally | Applicable onlyList
|
() |
Safety | Don't throw exceptions | High efficiency | Java 8+ Support |
() |
Safety | Don't throw exceptions | High efficiency | Java 8+ Support |
1. Use ()
The safest and recommended way is to use iterators. Iterator'sremove()
The method is designed for safe deletion during traversal.
List<String> list = new ArrayList<>(("A", "B", "C")); Iterator<String> iterator = (); while (()) { String element = (); if ("B".equals(element)) { (); } } (list); // Output: [A, C]
-
advantage: No exception throwing, suitable for multiple collections (
List
、Set
wait). - shortcoming: The code is relatively lengthy and requires explicit use of iterators.
2. for-each + Manually delete
If directlyfor-each
Deleting an element in a loop will be thrownConcurrentModificationException
。
List<String> list = new ArrayList<>(("A", "B", "C")); for (String element : list) { if ("B".equals(element)) { (element); // Throw ConcurrentModificationException } }
-
question: This method will cause exceptions because
for-each
Use an implicit iterator.
3. Reverse traversal for loop
Reverse traversalList
When , the index failure problem can be avoided. Iterator issues are avoided by directly accessing the index and deleting elements.
List<String> list = new ArrayList<>(("A", "B", "C")); for (int i = () - 1; i >= 0; i--) { if ("B".equals((i))) { (i); } } (list); // Output: [A, C]
- advantage: No iterator is needed, the code is clear.
-
shortcoming: Applicable only
List
, and the traversal direction is different from the usual one, which may increase the code complexity.
4. () (Java 8+)
Java 8 introducedremoveIf
The method is an easy and efficient way to remove elements that meet the criteria.
List<String> list = new ArrayList<>(("A", "B", "C")); ("B"::equals); (list); // Output: [A, C]
-
advantage: The syntax is concise, suitable for deleting elements that meet the criteria, suitable for
List
andSet
。 - shortcoming: Only available in Java 8 and later versions.
5. Use () (Java 8+)
Java 8 also introducedStream API
,passfilter
Methods can easily generate new collections that do not contain specified elements.
List<String> list = new ArrayList<>(("A", "B", "C")); list = () .filter(e -> !"B".equals(e)) .collect(()); (list); // Output: [A, C]
- advantage: The code is concise and easy to read, and the operations can be combined in chains.
- shortcoming: Generate a new collection, not operate on the original collection.
3. Common errors and consequences
-
Concurrent modification exception:
- When
for-each
When an element is deleted in a loop, it will be thrownConcurrentModificationException
。 -
reason:
for-each
Implicitly used iterators cannot synchronize the delete operation.
- When
-
Index crosses boundary:
- When directly deleted through the index, the size of the collection will change dynamically. If the index is not processed properly, it may cause
IndexOutOfBoundsException
。
- When directly deleted through the index, the size of the collection will change dynamically. If the index is not processed properly, it may cause
4. Demonstrate specific applications through cases
Case: Delete even numbers in the list
need: Delete all even numbers in the list and show the performance and code differences between different implementation methods.
List<Integer> numbers = new ArrayList<>((1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
Use Iterator to delete:
Iterator<Integer> iterator = (); while (()) { if (() % 2 == 0) { (); } } (numbers); // Output: [1, 3, 5, 7, 9]
Use removeIf:
(n -> n % 2 == 0); (numbers); // Output: [1, 3, 5, 7, 9]
Using Stream:
numbers = () .filter(n -> n % 2 != 0) .collect(()); (numbers); // Output: [1, 3, 5, 7, 9]
5. Summary and Supplement
-
Best Practices: Priority to use
Iterator
andremoveIf
Methods to delete elements in a collection, both of which are both efficient and safe in most scenarios. -
Performance optimization: When processing large-scale datasets,
removeIf
andStream
The performance is usually better than iterators, as they take advantage of the optimization of Lambda expressions and stream processing. -
Personal opinion: Choose the appropriate method according to the development scenario and code readability requirements. For conventional development,
removeIf
andStream
Most recommended. In the scenario where the original structure of the collection needs to be preserved,Iterator
More flexible.
With the above, you can have an in-depth understanding of how to delete elements during collection traversal, avoid common mistakes, and choose best practices that suit your project.
This is the article about the comparison, cases, common errors and consequences of java deleting elements during collection traversal. For more related Java collection traversal, please search for my previous article or continue browsing the related articles below. I hope everyone will support me in the future!