Java遍歷List並刪除某些元素


Java遍歷List並刪除某些元素

​ 在阿里的Java編程規約中有一條:【強制】不要在foreach循環里進行元素的remove/add操作。remove元素請使用Iterator方式,如果並發操作,需要對Iterator對象加鎖。

​ 這里不禁要問為什么?

​ 首先來試一下,遍歷List時刪除元素究竟行不行:

public class IteratorTest {

	public static void singleThreadRemove1(){
		List<String> list = new ArrayList<>();
		list.add("1");
		list.add("2");
		list.add("3");
		for (String l : list){
			if ("1".equals(l)){
				list.remove(l);
			}
		}
		System.out.println(list);
	}

	public static void main(String[] args){
		singleThreadRemove1();
	}

}

運行結果:

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
	at java.util.ArrayList$Itr.next(ArrayList.java:859)
	at blog.IteratorTest.singleThreadRemove1(IteratorTest.java:19)
	at blog.IteratorTest.main(IteratorTest.java:28)

Process finished with exit code 1

定位報錯日志可以發現,遍歷每個元素都會調用next()方法,next()方法首先有一個校驗:

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

這里modCount是指list實際修改的次數,expectedModCount是預計修改的次數,調用List的remove()方法只會增加modCount的值,而不會增加expectedModCount,也就是說這是Java在讓我們避免在for循環中刪除list的元素。

​ 要想知道為什么要避免這種操作很簡單,將上面程序中條件改為“當元素值等於‘2’時刪除元素”,此時會發現程序可以正常運行!當list遍歷完第二個元素時,這時准備進入第三個元素,然而list的元素數量已經減少,第三個索引位置上沒有元素,循環結束。這是多么荒唐的事啊,循環遍歷元素,明明有一個元素沒有走到,循環卻正常結束。


免責聲明!

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



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