This is one of the most popular interview questions recently asked in a job interview.
1. Rookie mistakes
Perhaps many beginners (including me, haha) first thought of writing is the following:
public static void main(String[] args) { List<String> platformList = new ArrayList<>(); Platformlist.add (" blog garden "); platformList.add("CSDN"); PlatformList. Add (" nuggets "); For (String platform: platformList) {if (platform.equals(" blog ")) {platformList.remove(platform); } } System.out.println(platformList); }Copy the code
Then with confidence to run, result unexpectedly throw Java. Util. Abnormal ConcurrentModificationException, translated into Chinese is: concurrent modification abnormalities.
Are you confused, wondering why?
Let’s first look at the bytecode generated by the above code, as follows:
As you can see, the foreach loop actually executes using Iterator, using hasNext () and next() as its core methods.
Now, how is the ArrayList class Iterator implemented?
As can be seen, when the next() method is called to get the next element, the first line of code is called checkForComodification(). The core logic of the method is to compare the values of the two variables, modCount and expectedModCount.
In the example above, the modCount and expectedModCount are both 3 at the beginning, so it is ok to get the “bloggarden” element the first time, but when you finish executing the following line:
platformList.remove(platform);
Copy the code
ModCount is changed to 4.
So on the second element, modCount and expectedModCount value is not equal, so throw out the Java. Util. ConcurrentModificationException anomalies.
Since we can’t use foreach to do this, how do we do it?
There are three main methods:
- Use Iterator’s remove() method
- Use the for loop to traverse in positive order
- Use the for loop to iterate backwards
Let’s go through them.
Python full set of materials, learning communication penguin skirt: 602697820
2. Use the remove() method of Iterator
Iterator’s remove() method is implemented as follows:
public static void main(String[] args) { List<String> platformList = new ArrayList<>(); Platformlist.add (" blog garden "); platformList.add("CSDN"); PlatformList. Add (" nuggets "); Iterator<String> iterator = platformList.iterator(); while (iterator.hasNext()) { String platform = iterator.next(); Iterator.remove (); if (platform.equals(" blog ")) {iterator.remove(); } } System.out.println(platformList); }Copy the code
The output is:
[CSDN, Denver]Copy the code
Iterator.remove (); Is that ok? Let’s take a look at the source code:
You can see, every time delete an element, modCount value will be assigned to again expectedModCount, so two variables are equal, not trigger Java. Util. ConcurrentModificationException anomalies. More interview questions, welcome to pay attention to the public number Java interview questions selected
Python full set of materials, learning communication penguin skirt: 602697820
3. Use the for loop to traverse in positive order
Positive traversal with the for loop is implemented as follows:
public static void main(String[] args) { List<String> platformList = new ArrayList<>(); Platformlist.add (" blog garden "); platformList.add("CSDN"); PlatformList. Add (" nuggets "); for (int i = 0; i < platformList.size(); i++) { String item = platformList.get(i); Platformlist. remove(I); if (item.equals(" blog-park ")) {platformList.remove(I); i = i - 1; } } System.out.println(platformList); }Copy the code
Delete an element from an array using the subscript of the array. The value of the subscript must be corrected after the element is deleted:
i = i - 1;
Copy the code
Why would I fix the value of the subscript? Because at the beginning the index of the element looks like this:
After the first loop removes the element “blogosphere”, the subscript of the element becomes the following:
In the second loop, the value of “I” is 1, which means that the element “CSDN” is skipped, so after deleting the element, we need to correct the subscript, which is also the code above I = i-1; The purpose of. More interview questions can be obtained by following the wechat subscription number
Python full set of materials, learning communication penguin skirt: 602697820
4. Use the for loop to iterate backwards
Reverse traversal with the for loop is implemented as follows:
public static void main(String[] args) { List<String> platformList = new ArrayList<>(); Platformlist.add (" blog garden "); platformList.add("CSDN"); PlatformList. Add (" nuggets "); for (int i = platformList.size() - 1; i >= 0; i--) { String item = platformList.get(i); If (item.equals(" equals ")) {platformList.remove(I); } } System.out.println(platformList); }Copy the code
This is done in the same way as if we were traversing through the for loop, except that we don’t have to fix the subscript, because we started with the element’s subscript:
After the first loop removes the element “nuggets”, the subscript of the element becomes the following:
In the second loop, I is 1, which means that the element CSDN is reached, which does not cause the element to be skipped, so there is no need to modify the subscript.