An ArrayList is deleted during the loop, will there be a problem and why?

The remove method in ArrayList (note that remove in ArrayList has two methods with the same name, but the input parameters are different, here is how the remove method whose input parameter is Object) is implemented:

    public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // Let gc do its work
    }

Execute the System.arraycopy method, resulting in the movement of array elements when deleting elements.

Delete method 1:

    public static void remove(ArrayList<String> list) {
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            if (s.equals("bb")) {
                list.remove(s);
            }
        }
    }

When traversing the second element string bb, because the deletion condition is met, the element is deleted from the array, and the next element (also the string bb) is moved to the current position, resulting in the next string bb in the next loop traversal It has not been traversed, so it cannot be deleted.
Even if element deletion occurs during reverse order traversal, it does not affect post-order element traversal.

Delete method 2:

    public static void remove(ArrayList<String> list) {
        for (String s : list) {
            if (s.equals("bb")) {
                list.remove(s);
            }
        }
    }

modCount+1, which involves iterator iteration.

    public E next() {
        checkForComodification();
        try {
            E next = get(cursor);
            lastRet = cursor++;
            return next;
        } catch (IndexOutOfBoundsException e) {
            checkForComodification();
            throw new NoSuchElementException();
        }
    }

Call the checkForCommodification() method

    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }

Using an iterator will avoid this:

Iterator<String> it = list.iterator();  
    while (it.hasNext()) {  
        String s = it.next();  
        if (s.equals("bb")) {  
            it.remove();  
        }  
    }  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325949405&siteId=291194637