This is a recent interview question that was asked in a job interview. This article summarizes and shares the question.

The article is from a wechat official account named Programmer Brother Wu

1. Rookie mistakes

Perhaps many beginners (including me, haha) first thought of writing is the following:

publicstaticvoidmain(String[]args){List<String>platformList=newArrayList<>(); Platformlist.add (" blog garden "); platformList.add("CSDN"); PlatformList. Add (" nuggets "); For (Stringplatform: platformList) {if (platform) equals (" blog garden ")) {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);

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.

2. Use the remove() method of Iterator

Iterator’s remove() method is implemented as follows:

publicstaticvoidmain(String[]args){List<String>platformList=newArrayList<>(); Platformlist.add (" blog garden "); platformList.add("CSDN"); PlatformList. Add (" nuggets "); Iterator<String>iterator=platformList.iterator(); while(iterator.hasNext()){Stringplatform=iterator.next(); Iterator.remove (); if(platform.equals(" blog ")){iterator.remove(); }}System.out.println(platformList); }Copy the code

The output is:

[CSDN, Denver]

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

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;

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, that is, the element “nuggets”, which causes the element “CSDN” to be 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

4. Use the for loop to iterate backwards

Reverse traversal with the for loop is implemented as follows:

publicstaticvoidmain(String[]args){List<String>platformList=newArrayList<>(); Platformlist.add (" blog garden "); platformList.add("CSDN"); PlatformList. Add (" nuggets "); for(inti=platformList.size()-1; i>=0; i--){Stringitem=platformList.get(i); If (item. Equals (" nuggets ")) {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.

Well, that’s all for this article. Thank you for reading it. If you like it, give it a triple link

As a programming learner, if you want to improve your programming ability, learn C/C++ programming knowledge and data structure, and strive to become a high-paying algorithm/software development engineer in the future!

C language C++ programming learning exchange circle, QQ group [464501141] wechat public number: C language programming learning base

Share (source code, project actual combat video, project notes, basic introduction tutorial)

Welcome to change careers and learn programming partners, use more information to learn and grow faster than their own thinking oh!

Programming learning books:

Programming learning video: