简体   繁体   中英

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

I have the following code that is throwing a 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?

Any help would be great thanks.

You need to gather all removals into a Set and remove them after all iterations are complete.

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?

If you call remove() without next() you'll get IllegalStateException

You are getting ConcurrentModificationException because you use 2 iterators on the same ArrayList and both of them removing elements from the list.

If you want to remove duplicates from the list, use can use @OldCurmudgeon code or just this 2 lines:

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. That is done by Shifting any subsequent elements to the left (subtracts one from their indices). System.arrayCopy method is used for that. 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. Since element at the position index is removed so elements starting from index+1 are copied to destination starting from 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM