可以用for循環直接刪除ArrayList的特定元素嗎?可能會出現什么問題?怎樣解決?


for循環直接刪除ArrayList中的特定元素是錯的,不同的for循環會發生不同的錯誤,泛型for會拋出 ConcurrentModificationException,普通的for想要刪除集合中重復且連續的元素,只能刪除第一個。
錯誤原因:打開JDK的ArrayList源碼,看下ArrayList中的remove方法(注意ArrayList中的remove有兩個同名方法,只是入參不同,這里看的是入參為Object的remove方法)是怎么實現的,一般情況下程序的執行路徑會走到else路徑下最終調用faseRemove方法,會執行System.arraycopy方法,導致刪除元素時涉及到數組元素的移動。針對普通for循環的錯誤寫法,在遍歷第一個字符串b時因為符合刪除條件,所以將該元素從數組中刪除,並且將后一個元素移動(也就是第二個字符串b)至當前位置,導致下一次循環遍歷時后一個字符串b並沒有遍歷到,所以無法刪除。針對這種情況可以倒序刪除的方式來避免。
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; // clear to let GC do its work
}
            
 
         
         
        
解決方案:用 Iterator:
public static void main(String[] args) {

        List<String> list = new ArrayList<>(Arrays.asList("a", "b" , "c", "d"));
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            if(iterator.next().equals("b")) {
                iterator.remove();
            }
        }
        System.out.println(list);
    }

 輸出結果:a, c, d





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM