What standard Java collections are safe during iteration?

Using for(Type x:collection){...} , which have widely used collection types, makes deleting x safe during iteration?

And is there a technical term for this in JavaDocs?

Clarification:

First, I asked for the use of for-each for(Type x:collection){...} syntax. However, a more complete answer will describe this style and use a regular Iterator-based loop where there are differences ... the question is which standard collections allow me to delete items during iteration, and how to iterate to resolve this.

+6
source share
3 answers

One such collection is CopyOnWriteArrayList . Other collections in the java.util.concurrent package provide this function.

The fact that their iterators never throw a ConcurrentModificationException is a side effect of the copy-on-write semantics of this class: every time you change it, the main array will be copied. This is done to provide quick, simultaneous access to frequently read but rarely edited lists.

JavaDoc explains this as follows (emphasis mine):

The snapshot style iterator method uses a reference to the state of the array at the point at which the iterator was created. This array never changes during the life of the iterator, so no interference is possible, and the iterator is guaranteed not to throw a ConcurrentModificationException .

In addition to the high cost of upgrades, this implementation has some additional disadvantages:

The iterator will not display additions, deletions, or changes to the list since the creation of the iterator. The operations of changing elements in the iterators themselves ( remove , set and add ) are not supported. These methods throw an UnsupportedOperationException .

Please note that these collections are not intended for the convenience of a β€œsimple” loop and deletion, but are specialized collections for use in situations with a high level of concurrency, when many threads need simultaneous access to data that can still change (but usually rarely changes ) Don't just replace each ArrayList with CopyOnWriteArrayList .

+5
source

Typically, the thumb: Anything w / Concurrent or Blocking in its name, otherwise. ConcurrentLinkedList , ConcurrentSkipListSet , LinkedBlockingDeque , LinkedBlockingQueue , etc. KeySet (), values ​​() of ConcurrentHashMap and ConcurrentSkipListMap, etc. Most java.util.concurrent ConcurrentModificationException , and that is good.

COWArrayList is usually useful for smaller or rarely modified collections ... and you should avoid the explicit set method.

One important note: using iterator.remove should always be preferred for Collection.remove (except for CHM.entrySet (), which is a bug in the buggy) (when available, the COWArrayList iterator does not support deletion). All non-random access structures will benefit from having to look for an element, which may be O (n).

Overall, ConcurrentModificationException was a half-baked idea and its implication. includes some side effects, including preventing the operation of hardware-transactional memory. This requires additional performance costs that are rarely needed. HashMap makes a terrible sense. w / volatile modCount (which is written upon modification and read on each itearyion, read is sorta free on x86, though).

0
source

Probably a bit late answer, but Java 8 makes it easy to remove items from the collection during iteration:

 removeIf(Predicate<? super E> filter) 

Deletes all elements of this collection that satisfy the given predicate.

-1
source

Source: https://habr.com/ru/post/916091/


All Articles