Loop to delete elements in List

Cyclic deletion of elements in the List, this problem requires attention, if you are a novice, you will indeed encounter a little trouble

For example, there is the following List:

public List<String> initList = Arrays.asList("Zhang San", "Li Si", "Monday", "Liu Si", "Li Qiang", "Li Bai");

1. Normal for loop deletion (unreliable)

/**
 * Ordinary for loop deletion
 * @author: stack length
 * @from: public account Java technology stack
 */
@Test
public void remove1() {     List<String> list = new ArrayList(initList);     for (int i = 0; i < list.size(); i++) {         String str = list.get(i);         if (str.startsWith("Lee")) {             list.remove(i);         }     }     System.out.println( list); }








The problem lies in list.size(), because both list.size() and i change dynamically, the value of i keeps accumulating, and list.size() keeps decreasing, so the list will end the loop early.

Therefore, although this method will not report an error, there are hidden dangers and it is not easy to be detected. It is not recommended to use

2. Ordinary for loop extracts variables and deletes (throws an exception)

/**
 * Ordinary for loop deletion (size proposes variables)
 * @author: stack length
 * @from: public account Java technology stack
 */
@Test
public void remove2() {     List<String> list = new ArrayList(initList);     int size = list.size();     for (int i = 0; i < size; i++) {         String str = list.get(i);         if (str.startsWith("Lee")) {             list.remove(i );         }     }     System.out.println(list); }









Directly dry the subscript overflow exception. It is also obvious here, because the size variable is fixed, but the actual size of the list is constantly decreasing, and the size of i is constantly accumulating. Once i >= the actual size of the list, it will definitely be abnormal.

3. Ordinary for loop delete in reverse order (reliable)

/**
 * Ordinary for loop delete in reverse order
 * @author: stack length
 * @from: public account Java technology stack
 */
@Test
public void remove3() {     List<String> list = new ArrayList(initList);     for (int i = list.size() - 1; i > 0; i--) {         String str = list.get(i);         if (str.startsWith("Lee")) {             list.remove(i);         }     }     System .out.println(list); }








Output result: [Zhang San, Monday, Liu Si]

The result output is normal. This deletion method is OK even if list.size() is put out of the variable, because it is only used once in the loop.

4. Enhanced for loop deletion (exception thrown)

/**
 * Enhanced for loop deletion
 * @author: stack length
 * @from: public account Java technology stack
 */
@Test
public void remove3() {     List<String> list = new ArrayList(initList);     for (String element: list) {         if (element.startsWith("Lee")) {             list.remove(element);         }     }     System.out.println(list); }







An exception was thrown again. However, this exception is different from the subscript exception above. This time it is: java.util.ConcurrentModificationException. This is one of the very common exceptions in collection operations, that is, concurrent modification exception!

5. Iterator loop iterator delete (reliable)

/**
 * Iterator loop deletion (iterator.remove)
 * @author: stack length
 * @from: public account Java technology stack
 */
@Test
public void remove4() {     List<String> list = new ArrayList(initList);     for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {         String str = iterator.next();         if (str.contains("李")) {             iterator.remove();         }     }     System.out.println(list); }








Output result: [Zhang San, Monday, Liu Si]

6. Iterator loop collection deletion (throws an exception)

/**
 * Iterator loop deletion (list.remove)
 * @author: stack length
 * @from: public account Java technology stack
 */
@Test
public void remove5() {     List<String> list = new ArrayList(initList);     for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {         String str = ite.next();         if (str.contains("Lee")) {             list.remove(str);         }     }     System.out.println(list); }








It’s that concurrent modification exception again. Although this example uses an Iterator loop, it uses the list.remove method when deleting. This is also problematic. Be careful, don’t use it wrong.

7. The collection forEach method is cyclically deleted (throws an exception)

/**
 * list.forEach delete
 * @author: stack length
 * @from: public account Java technology stack
 */
@Test
public void remove6() {     List<String> list = new ArrayList(initList);     list.forEach((( e) -> {         if (e.contains("Lee")) {             list.remove(e);         }     });     System.out.println(list); }







It's that concurrent modification exception again.

8. stream filter (reliable)

/**
 * stream filter filter
 * @author: stack length
 * @from: public account Java technology stack
 */
@Test
public void remove7() {     List<String> list = new ArrayList(initList);     list = list.stream( ).filter(e -> !e.startsWith("Lee")).collect(Collectors.toList());     System.out.println(list); }



Summarize:

  • Ordinary for loop deletion in reverse order (reliable)

  • iterator loop iterator delete (reliable)

  • stream filter filter (reliable)

There are only 3 reliable and feasible solutions, and only 2 orthodox deletion methods, but be careful not to use the wrong method.

Like it if you feel good!

Guess you like

Origin blog.csdn.net/qq_25462179/article/details/132322443