There are many ways to traverse and delete elements in a List or Map, and problems will occur when used improperly. Let’s learn more through this article.
1. Delete elements during List traversal
Use index subscript traversal
Example: Delete 2 in the list
public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); for (int i = 0; i < list.size(); i++) { if(2 == list.get(i)){ list.remove(i); } System.out.println(list.get(i)); } System.out.println("list=" + list.toString()); }
Output result:
1 2 3 4 list=[1, 2, 3, 4]
Problem:
The result shows only delete One 2 was deleted, and the other 2 was omitted. The reason is: after deleting the first 2, the number of elements in the set was reduced by 1, and the subsequent elements were moved forward by 1 position, resulting in the second 2 being omitted. .
Use For loop traversal
Example:
public static void listIterator2(){ List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); for (int value : list) { if(2 == value){ list.remove(value); } System.out.println(value); } System.out.println("list=" + list.toString()); }
Result:
Exception in thread "main" 1 2 java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at test.ListIterator.listIterator2(ListIterator.java:39) at test.ListIterator.main(ListIterator.java:10)
Description:
Description of ConcurrentModificationException in jdk:
public class ConcurrentModificationException extends
RuntimeException This exception is thrown when a method detects concurrent modification of an object, but does not allow such modification.
For example, when one thread iterates over a Collection, another thread is usually not allowed to linearly modify the Collection. Often in these cases, the results of the iteration are indeterminate. Some iterator implementations (including all generic collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that perform this operation are called fail-fast iterators because the iterator fails completely quickly without risking arbitrary unspecified behavior at some time in the future.
Note: This exception will not always indicate that the object has been modified concurrently by different threads. An object may throw this exception if a single thread issues a sequence of method calls that violates the object's contract. For example, if a thread directly modifies a collection while iterating over it using a fail-fast iterator, the iterator will throw this exception.
Note: The fail-fast behavior of iterators is not guaranteed because, in general, it is not possible to make any hard guarantees about whether unsynchronized concurrent modifications will occur. Fail-fast operations throw a ConcurrentModificationException on a best-effort basis. Therefore, it is a mistake to write a program that relies on this exception to improve the correctness of such operations. The correct approach is: ConcurrentModificationException should only be used to detect bugs.
For each in Java actually uses an iterator for processing. The iterator does not allow the collection to be deleted during the use of the iterator. So it caused the iterator to throw ConcurrentModificationException.
The correct way
Example:
public static void listIterator3(){ List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); Iterator<Integer> it = list.iterator(); while (it.hasNext()){ Integer value = it.next(); if (2 == value) { it.remove(); } System.out.println(value); } System.out.println("list=" + list.toString()); }
Result:
1 2 2 3 4 list=[1, 3, 4]
2. Deleting elements during Map traversal
Example of the correct approach:
public static void main(String[] args) { HashMap<String, String> map = new HashMap<String, String>(); map.put("1", "test1"); map.put("2", "test2"); map.put("3", "test3"); map.put("4", "test4"); //完整遍历Map for (Entry<String, String> entry : map.entrySet()) { System.out.printf("key: %s value:%s\r\n", entry.getKey(), entry.getValue()); } //删除元素 Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while(it.hasNext()) { Map.Entry<String, String> entry= it.next(); String key= entry.getKey(); int k = Integer.parseInt(key); if(k%2==1) { System.out.printf("delete key:%s value:%s\r\n", key, entry.getValue()); it.remove(); } } //完整遍历Map for (Entry<String, String> entry : map.entrySet()) { System.out.printf("key: %s value:%s\r\n", entry.getKey(), entry.getValue()); } }
Result:
key: 1 value:test1 key: 2 value:test2 key: 3 value:test3 key: 4 value:test4 delete key:1 value:test1 delete key:3 value:test3 key: 2 value:test2 key: 4 value:test4
Note
But there are also things we need to pay attention to about the remove() method of iterator:
Every time the iterator.next() method is called, the remove() method can only be called once.
Before calling the remove() method, the next() method must be called once.
Description of the remove() method in JDK-API:
void remove() removes the last element returned by the iterator from the collection pointed to by the iterator (optional operation). This method can only be called once per call to next. The behavior of an iterator is undefined if the collection pointed to by the iterator is modified while it is being iterated in a manner other than by calling this method.
Throws: UnsupportedOperationException - if the iterator does not support the remove operation. IllegalStateException - if the next method has not been called, or the remove method has been called since the last call to the next method.
Summary
The above is all about deleting elements during the traversal process of List and Map. I hope the content of this article can bring some help to everyone's study or work. If you have any questions, you can leave a message to communicate.
For more articles on how to delete elements during List or Map traversal in Java, please pay attention to the PHP Chinese website!