简体   繁体   English

从 ArrayList 同时删除两个对象而不导致 ConcurrentModificationException?

[英]Remove two objects at the same time from an ArrayList without causing a ConcurrentModificationException?

I have the following code that is throwing a ConcurrentModificationException.我有以下代码抛出 ConcurrentModificationException。 Can someone please explain why this is happening?有人可以解释为什么会这样吗?

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

Is it the case that I can only call iterator.remove() once for each iterator.next() call, and that calling remove twice before the next call to iterator.next() is causing this?对于每个 iterator.next() 调用,我只能调用 iterator.remove() 一次,并且在下一次调用 iterator.next() 之前调用 remove 两次会导致这种情况吗?

Any help would be great thanks.任何帮助都会非常感谢。

You need to gather all removals into a Set and remove them after all iterations are complete.您需要将所有删除收集到一个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);
}

Is it the case that I can only call iterator.remove() once for each iterator.next() call, and that calling remove twice before the next call to iterator.next() is causing this?对于每个 iterator.next() 调用,我只能调用 iterator.remove() 一次,并且在下一次调用 iterator.next() 之前调用 remove 两次会导致这种情况吗?

If you call remove() without next() you'll get IllegalStateException如果你在没有next()情况next()调用remove() next()你会得到IllegalStateException

You are getting ConcurrentModificationException because you use 2 iterators on the same ArrayList and both of them removing elements from the list.您收到ConcurrentModificationException是因为您在同一个 ArrayList 上使用了 2 个迭代器,并且它们都从列表中删除了元素。

If you want to remove duplicates from the list, use can use @OldCurmudgeon code or just this 2 lines:如果要从列表中删除重复项,可以使用 @OldCurmudgeon 代码或仅使用以下 2 行:

bets.clear();
bets.addAll(new LinkedHashSet(bets));

When elements are removed from an ArrayList in Java using either remove(int i) (ie using index) or remove(Object o), gap created by the removal of an element has to be filled in the underlying array.当使用 remove(int i)(即使用索引)或 remove(Object o) 从 Java 中的 ArrayList 中删除元素时,必须在底层数组中填充因删除元素而产生的间隙。 That is done by Shifting any subsequent elements to the left (subtracts one from their indices).这是通过将任何后续元素向左移动(从它们的索引中减去一个)来完成的。 System.arrayCopy method is used for that. System.arrayCopy 方法用于此目的。 Process can also be called as shuffling.过程也可以称为混洗。

System.arraycopy(elementData, index+1, elementData, index, numMoved);

Here index+1 is the source position and index is the destination position.这里 index+1 是源位置,index 是目标位置。 Since element at the position index is removed so elements starting from index+1 are copied to destination starting from index.由于位置 index 处的元素被删除,因此从 index+1 开始的元素被复制到从 index 开始的目的地。

You are doing this operation in a loop it becomes difficult for the Arraylist to maintain a definite state at a given instant, and hence some changes may be lost, to avoid this we have Concurrentmodification exception.您在循环中执行此操作,Arraylist 在给定时刻保持确定状态变得困难,因此可能会丢失一些更改,为了避免这种情况,我们有 Concurrentmodification 异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从ArrayList中删除随机项目,导致ConcurrentModificationException - Remove Random Item From ArrayList Causing ConcurrentModificationException 如果某个元素存在于另一个元素中,则从Arraylist中删除它们,而不会引发ConcurrentModificationException - Remove elements from an Arraylist if they are present in another one without raising ConcurrentModificationException Java在没有ConcurrentModificationException的情况下在同一循环中添加/删除 - Java add/remove at the same loop without ConcurrentModificationException 如何使用线程将对象添加到列表并同时使用该列表而不会获得 ConcurrentModificationException? - How to add objects to a list with a thread and use the list at the same time without getting ConcurrentModificationException? 如何使用 Arraylist 中的命令行同时删除两个对象 - How to remove two object at the same time using command line from an Arraylist 从ArrayList中删除对象时如何避免ConcurrentModificationException - How to avoid a ConcurrentModificationException when removing objects from an ArrayList 从ArrayList中删除对象 - Remove objects from ArrayList 从ArrayList中删除标记:java.util.ConcurrentModificationException - Remove the marker from the ArrayList: java.util.ConcurrentModificationException 将两个arrayList引用到相同的对象 - Reference of two arrayList to same objects ConcurrentModificationException,但不从ArrayList中删除任何内容 - ConcurrentModificationException but not removing anything from ArrayList
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM