java修改集合拋出ConcurrentModificationException異常

測試代碼爲:
html

public static void main(String[] args) {
		List<String> strList = new ArrayList<String>();
		strList.add("1");
		strList.add("2");
		strList.add("3");
		strList.add("4");
		for(String str:strList){
			if(str.equals("4")){
				strList.remove(str);
			}
		}
	}

運行後結果以下:
java

跟蹤代碼,拋出異常的地方具體在:函數

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

遍歷時返回一個元素以前,會調用checkForComodification()函數進行檢查,該函數實現爲:測試

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

    modCount 爲ArrayList修改的次數,expectedModCount 爲指望修改的次數,在刪除第四個元素以前,modCount 和expectedModCount 均爲4(4次add),而調用ArrayList的remove()方法後,modCount 變爲5,但該方法未修改expectedModCount ,其值仍爲4,所以出現上述異常。spa

    解決方法爲:單線程環境中,使用 Iterator的remove()方法取代ArrayList的remove()方法,能夠避免ConcurrentModificationException異常。線程

    巧合的是,若是要刪除的元素正好是集合中倒數第二個元素,則不會拋出此異常。Iterator遍歷獲取一個元素以前會先調用hasNext()方法來判斷是否還有元素,該方法實現爲:code

public boolean hasNext() {
            return cursor != size();
	}

其中cursor爲遍歷的位置,從0開始,在上面的next()方法中被更新。htm

    刪除倒數第二個元素"3"後,已經訪問了3個元素,cursor指向下一個應該訪問的元素位置,即3,而size()也返回3,hasNext()返回false,就不會調用next()方法,所以也不存在ConcurrentModificationException異常blog

    刪除元素"4"後,cursor的值變爲4,而size()返回3,hasNext()返回true,所以調用next()方法時就會拋出ConcurrentModificationException異常rem



附上一篇資料:

Java ConcurrentModificationException異常緣由和解決方法:

http://www.cnblogs.com/dolphin0520/p/3933551.html

相關文章
相關標籤/搜索