![](/img/trans.png)
[英]Remove Random Item From ArrayList Causing ConcurrentModificationException
[英]Remove two objects at the same time from an ArrayList without causing a ConcurrentModificationException?
我有以下代碼拋出 ConcurrentModificationException。 有人可以解釋為什么會這樣嗎?
public void foo(ArrayList<Bet> bets)
Iterator it1 = bets.iterator();
while(it1.hasNext())
Bet b1 = (Bet) bets.next()
Iterator it2 = bets.iterator();
while(it2.hasNext())
if(bet1.equals(bet2))
it2.remove();
it1.remove(); //ConcurrentModificationException thrown here
對於每個 iterator.next() 調用,我只能調用 iterator.remove() 一次,並且在下一次調用 iterator.next() 之前調用 remove 兩次會導致這種情況嗎?
任何幫助都會非常感謝。
您需要將所有刪除收集到一個Set
,並在所有迭代完成后將其刪除。
public void foo(ArrayList<Bet> bets) {
Set<Bet> remove = new HashSet<Bet>();
for ( Bet bet1 : bets ) {
for ( Bet bet2 : bets ) {
// Not the same but equal.
if ( bet1 != bet2 && bet1.equals(bet2)) {
remove.add(bet1);
remove.add(bet2);
}
}
}
bets.removeAll(remove);
}
對於每個 iterator.next() 調用,我只能調用 iterator.remove() 一次,並且在下一次調用 iterator.next() 之前調用 remove 兩次會導致這種情況嗎?
如果你在沒有next()
情況next()
調用remove()
next()
你會得到IllegalStateException
您收到ConcurrentModificationException
是因為您在同一個 ArrayList 上使用了 2 個迭代器,並且它們都從列表中刪除了元素。
如果要從列表中刪除重復項,可以使用 @OldCurmudgeon 代碼或僅使用以下 2 行:
bets.clear();
bets.addAll(new LinkedHashSet(bets));
當使用 remove(int i)(即使用索引)或 remove(Object o) 從 Java 中的 ArrayList 中刪除元素時,必須在底層數組中填充因刪除元素而產生的間隙。 這是通過將任何后續元素向左移動(從它們的索引中減去一個)來完成的。 System.arrayCopy 方法用於此目的。 過程也可以稱為混洗。
System.arraycopy(elementData, index+1, elementData, index, numMoved);
這里 index+1 是源位置,index 是目標位置。 由於位置 index 處的元素被刪除,因此從 index+1 開始的元素被復制到從 index 開始的目的地。
您在循環中執行此操作,Arraylist 在給定時刻保持確定狀態變得困難,因此可能會丟失一些更改,為了避免這種情況,我們有 Concurrentmodification 異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.