This is an interview question I was asked recently. This blog summarizes and shares this question. 1. Common mistakes made by beginnersMaybe many novices (including me back then, haha) would first think of writing something like this: public static void main(String[] args) { List<String> platformList = new ArrayList<>(); platformList.add("博客园"); platformList.add("CSDN"); platformList.add("Nuggets"); for (String platform : platformList) { if (platform.equals("博客园")) { platformList.remove(platform); } } System.out.println(platformList); } Then I ran it with confidence, but it turned out to be Are you confused and wondering why this is happening? Let's first look at the bytecode generated by the above code, as shown below: From this we can see that when the foreach loop is actually executed, it actually uses Iterator, and the core methods used are hasnext() and next(). Then let’s take a look at how the Iterator of the ArrayList class is implemented? It can be seen that when the next() method is called to get the next element, the first line of code is to call checkForComodification();, and the core logic of this method is to compare the values of the two variables modCount and expectedModCount. In the above example, at the beginning, the values of modCount and expectedModCount are both 3, so there is no problem in getting the element "博客园" for the first time, but when the following line of code is executed: platformList.remove(platform); The value of modCount is changed to 4. So when getting the element for the second time, the values of modCount and expectedModCount are not equal, so the error is thrown. Since foreach cannot be used to achieve this, how can we implement it? There are three main methods:
Next, I will explain them one by one. 2. Use the remove() method of IteratorThe implementation of the remove() method using Iterator is as follows: public static void main(String[] args) { List<String> platformList = new ArrayList<>(); platformList.add("博客园"); platformList.add("CSDN"); platformList.add("Nuggets"); Iterator<String> iterator = platformList.iterator(); while (iterator.hasNext()) { String platform = iterator.next(); if (platform.equals("博客园")) { iterator.remove(); } } System.out.println(platformList); } The output is:
Why can we use iterator.remove()? Let's look at its source code: It can be seen that each time an element is deleted, the value of modCount is reassigned to expectedModCount, so that the two variables are equal and will not trigger 3. Use for loop to traverse in positive orderThe implementation of forward traversal using a for loop is as follows: public static void main(String[] args) { List<String> platformList = new ArrayList<>(); platformList.add("博客园"); platformList.add("CSDN"); platformList.add("Nuggets"); for (int i = 0; i < platformList.size(); i++) { String item = platformList.get(i); if (item.equals("博客园")) { platformList.remove(i); i = i - 1; } } System.out.println(platformList); } This implementation is relatively easy to understand, that is, to delete by array subscript, but there is a note that after deleting the element, the subscript value must be corrected: i = i - 1; Why do we need to correct the value of the subscript? Because the initial element subscript is like this: After deleting the element "博客园" in the first loop, the subscript of the element becomes as follows: In the second loop, the value of i is 1, which means that the element "Nuggets" is taken, which causes the element "CSDN" to be skipped. Therefore, after deleting the element, we need to correct the subscript, which is also the purpose of i = i - 1; in the above code. For more interview questions, you can follow the WeChat subscription number Jiangjiji and reply to the interview to get 4. Use for loop to traverse in reverse orderThe implementation of reverse traversal using a for loop is as follows: public static void main(String[] args) { List<String> platformList = new ArrayList<>(); platformList.add("博客园"); platformList.add("CSDN"); platformList.add("Nuggets"); for (int i = platformList.size() - 1; i >= 0; i--) { String item = platformList.get(i); if (item.equals("Nuggets")) { platformList.remove(i); } } System.out.println(platformList); } This implementation is similar to using a for loop to traverse in forward order, but there is no need to correct the subscripts because the subscripts of the elements at the beginning are like this: After deleting the element "Nuggets" in the first loop, the subscripts of the elements become as follows: In the second loop, the value of i is 1, which means that the element "CSDN" is obtained, which will not cause the element to be skipped, so there is no need to correct the subscript. So when getting the element for the second time, the values of modCount and expectedModCount are not equal, so the error is thrown. Since foreach cannot be used to achieve this, how can we implement it? There are three main methods:
Next, I will explain them one by one. 5. Use Iterator’s remove() methodThe implementation of the remove() method using Iterator is as follows: public static void main(String[] args) { List<String> platformList = new ArrayList<>(); platformList.add("博客园"); platformList.add("CSDN"); platformList.add("Nuggets"); Iterator<String> iterator = platformList.iterator(); while (iterator.hasNext()) { String platform = iterator.next(); if (platform.equals("博客园")) { iterator.remove(); } } System.out.println(platformList); } The output is:
Why can we use iterator.remove()? Let's look at its source code: It can be seen that each time an element is deleted, the value of modCount is reassigned to expectedModCount, so that the two variables are equal and will not trigger 6. Use for loop to traverse in positive orderThe implementation of forward traversal using a for loop is as follows: public static void main(String[] args) { List<String> platformList = new ArrayList<>(); platformList.add("博客园"); platformList.add("CSDN"); platformList.add("Nuggets"); for (int i = 0; i < platformList.size(); i++) { String item = platformList.get(i); if (item.equals("博客园")) { platformList.remove(i); i = i - 1; } } System.out.println(platformList); } This implementation is relatively easy to understand, that is, to delete by array subscript, but there is a note that after deleting the element, the subscript value must be corrected: i = i - 1; Why do we need to correct the value of the subscript? Because the initial element subscript is like this: After deleting the element "博客园" in the first loop, the subscript of the element becomes as follows: In the second loop, the value of i is 1, which means that the element "Nuggets" is taken, which causes the element "CSDN" to be skipped. Therefore, after deleting the element, we need to correct the subscript, which is also the purpose of i = i - 1; in the above code. For more interview questions, you can follow the WeChat subscription number Jiangjiji and reply to the interview to get 7. Use for loop to traverse in reverse orderThe implementation of reverse traversal using a for loop is as follows: public static void main(String[] args) { List<String> platformList = new ArrayList<>(); platformList.add("博客园"); platformList.add("CSDN"); platformList.add("Nuggets"); for (int i = platformList.size() - 1; i >= 0; i--) { String item = platformList.get(i); if (item.equals("Nuggets")) { platformList.remove(i); } } System.out.println(platformList); } This implementation is similar to using a for loop to traverse in forward order, but there is no need to correct the subscripts because the subscripts of the elements at the beginning are like this: After deleting the element "Nuggets" in the first loop, the subscripts of the elements become as follows: In the second loop, the value of i is 1, which means that the element "CSDN" is obtained, which will not cause the element to be skipped, so there is no need to correct the subscript. This is the end of this article about whether to use MySQL or Redis for the like function. For more relevant MySQL\Redis like content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: Core skills that web front-end development engineers need to master
>>: The most common declaration merge in TS (interface merge)
This article example shares the specific code for...
Preface BINARY and VARBINARY are somewhat similar...
I don't know when it started, but every time ...
This article example shares the specific code of ...
A simple calculator written in WeChat applet for ...
Table of contents 1. Introduction Second practice...
This article example shares the specific code of ...
This article shares the specific code of Vue usin...
This article example shares the specific code of ...
Table of contents 1. Brief Overview 2. JSON basic...
Table of contents First of all, you need to know ...
Table of contents 1. Effect diagram (multiple col...
1. DNS server concept Communication on the Intern...
background Sometimes we need to get the creation ...
In a recent project, I wanted to align text verti...