There are a number of ways to traverse the deletion of elements in a list or map, which can cause problems when used improperly. The following article to learn more about it.
Delete elements during the list traversal
How to use index subscript traversal
Example: Removing 2 from a 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 results:
1
2
3
4
list=[1, 2, 3, 4]
Problem:
The results show that only one 2 is deleted, and the other 2 is omitted because: after the first 2 is deleted, the number of elements in the collection is reduced by 1, and the following elements move 1, causing the second 2 to be omitted.
Using the For Loop traversal method
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 ());
}
Results:
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 the method detects concurrent modifications to the object, but does not allow this modification.
For example, when a thread iterates over a Collection, it usually does not allow another linear modification of the Collection. Usually in these cases, the result of the iteration is indeterminate. If this behavior is detected, some iterator implementations (including all common collection implementations provided by the JRE) may choose to throw this exception. The iterator that performs this operation is called a fast fail iterator, because the iterator will soon fail completely without risking any uncertainty at any future time.
Note : This exception does not always indicate that the object has been modified concurrently by different threads. The object may throw this exception if a single-threaded emit a method call sequence that violates an object contract. For example, an iterator throws this exception if the thread modifies the collection directly when it uses the quick fail iterator to collection over the iteration.
Note : The rapid failure behavior of iterators is not guaranteed because, in general, it is not possible to make any hard guarantees about whether or not to have a different step of concurrent modification. A quick fail operation will do its best to throw ConcurrentModificationException
. Therefore, it is a bad idea to write a program that relies on this exception to improve the correctness of this type of operation: It ConcurrentModificationException
should only be used to detect bugs.
The for each in Java is actually used by iterator for processing. The iterator does not allow collections to be deleted during iterator use. So that caused the iterator to throw out ConcurrentModificationException
.
The right 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 ());
}
Results:
Second, the map traversal process to delete elements
Examples of correct practices:
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");
Full traversal of the map
for (entry<string, string> entry:map.entrySet ()) {
System.out.printf ("Key:%s value:%s\r\n", Entry.getkey (), Entry.getvalue ());
Delete element
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 ();
}
Full traversal
of map for (entry<string, string> entry:map.entrySet ()) {
System.out.printf ("Key:%s value:%s\r\n ", Entry.getkey (), Entry.getvalue ());
}
Results:
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
Attention
But for the iterator remove()
approach, there are also areas that need our attention:
iterator.next()
only one method can be called once per method is invoked remove()
.
remove()
a method must be called once before the method is invoked next()
.
Description of the Remove () method in Jdk-api:
void remove()
Removes the last element returned by the iterator (optional operation) from the collection pointed to by the iterator. This method can only be called once per call to next. The behavior of the iterator is ambiguous if the collection pointed to by the iterator is modified in an iterative manner other than by calling this method.
Thrown: UnsupportedOperationException
-If the iterator does not support remove
operations. IllegalStateException
-If the method has not been called next
, or the method next
has been called after the method was last called remove
.
Summarize
The above is about the list and map traversal process to delete the entire content of elements, I hope this article on the content of everyone's study or work can bring some help, if you have questions you can message exchange.