remove elements from CopyOnWriteArrayList

前端 未结 9 1954
醉酒成梦
醉酒成梦 2020-12-29 09:27

I am getting an exception when I try to remove elements from CopyOnWriteArrayList using an iterator. I have noticed that it is documented

Element-c

相关标签:
9条回答
  • 2020-12-29 10:17

    EDIT: I'm an idiot. I missed the fact that this is a copy-on-write list so every removal means a new copy. So my suggestions below are likely to be suboptimal if there's more than one removal.

    Same as for any other list whose iterator doesn't support remove, or anything where you're not using an iterator. There are three basic techniques that come to mind to avoid this bug:

    1. Decrement the index after removing something (being careful not to do anything with the index until the next iteration). For this you'll obviously have to use a for(int i=0; i < ... style of for loop, so that you can manipulate the index.

    2. Somehow repeat what the inside of the loop is doing, without literally going back to the top of the loop. Bit of a hack - I would avoid this technique.

    3. Iterate over the list in reverse (from end to start, instead of from start to end). I prefer this approach as it's the simplest.

    0 讨论(0)
  • 2020-12-29 10:20

    Something like this:

    int pos = 0;
    while(pos < lst.size() ) {
      Foo foo = lst.get(pos);
      if( hasToBeRemoved(foo) ) {
        lst.remove(pos);
        // do not move position
      } else {
        pos++;
      }
    }
    
    0 讨论(0)
  • 2020-12-29 10:21

    the shortest and most efficient way:

    List<String> list = new CopyOnWriteArrayList<>();
    list.removeIf(s -> s.length() < 1);
    

    internally it creates an temporary array with the same length and copies all elements where the predicate returns true.

    keep in mind that if you use this method to actually iterate over the elements to perform some action, these actions cannot be performed in paralell anymore since the removeIf-call is atomic and will lock the traversal for other threads

    0 讨论(0)
提交回复
热议问题