Java 在不引起ConcurrentModificationException的情况下,同时从ArrayList中删除两个对象?
我有以下代码抛出ConcurrentModificationException。 有人能解释一下为什么会这样吗Java 在不引起ConcurrentModificationException的情况下,同时从ArrayList中删除两个对象?,java,iterator,iteration,concurrentmodification,Java,Iterator,Iteration,Concurrentmodification,我有以下代码抛出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.hasNe
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
public void foo(ArrayList下注)
迭代器it1=bets.Iterator();
while(it1.hasNext())
下注b1=(下注)下注。下一步()
迭代器it2=bets.Iterator();
while(it2.hasNext())
if(bet1.等于(bet2))
it2.删除();
it1.删除()//此处抛出ConcurrentModificationException
是不是每次调用iterator.next()时只能调用iterator.remove()一次,
在下一次调用iterator.next()之前调用remove两次会导致这种情况吗
任何帮助都将非常感谢。您需要将所有删除内容收集到
集合中,并在所有迭代完成后删除它们
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);
}
public void foo(ArrayList下注){
Set remove=newhashset();
用于(下注bet1:下注){
用于(下注bet2:下注){
//不一样但相等。
如果(bet1!=bet2&&bet1.equals(bet2)){
删除。添加(bet1);
删除。添加(bet2);
}
}
}
下注。移除所有(移除);
}
是不是每次只能调用iterator.remove()一次
iterator.next()调用,该调用在下一次调用之前删除两次
调用iterator.next()会导致这种情况吗
如果调用remove()
您得到的是ConcurrentModificationException
,因为您在同一ArrayList上使用了两个迭代器,并且这两个迭代器都从列表中删除了元素
如果要从列表中删除重复项,请使用@OldCurmudgeon代码或仅此两行:
bets.clear();
bets.addAll(new LinkedHashSet(bets));
当使用remove(inti)(即使用index)或remove(objecto)从Java中的ArrayList中删除元素时,必须在底层数组中填充删除元素所产生的间隙。这是通过将任何后续元素向左移动(从其索引中减去一个)来实现的。为此使用System.arrayCopy方法。这个过程也可以称为洗牌
System.arraycopy(elementData, index+1, elementData, index, numMoved);
这里索引+1是源位置,索引是目标位置。由于位置索引处的元素被删除,所以从索引+1开始的元素被复制到从索引开始的目标
您在循环中执行此操作,Arraylist在给定的瞬间很难保持确定的状态,因此可能会丢失一些更改,为了避免这种情况,我们有Concurrentmodification异常。虽然这是一个旧答案,但在使用removeAll
时要小心-它具有指数运行时间(max)取决于要删除的元素的数量。RemoveAll倾向于O(n^2),因为它重复使用contains方法。@user2780757这离O(e^n)还有很长的路要走哦,哈哈,我明白了,对此表示歉意。只要一个人明白了重点,我就没事:-)