Grigor
Grigor

Reputation: 3

How to remove element from list safely

for (Iterator<Long> it = ids.iterator(); it.hasNext(); ) {
    Long temp = it.next().longValue();
    if (oo.contains(temp)) {
        it.remove();
    }
}

Did I get it right?
If I use iterator remove() for both single and multi threaded environments, will I not get any ConcurrentModificationException or some other exception either?

Upvotes: 0

Views: 709

Answers (1)

Sweeper
Sweeper

Reputation: 274650

If I use iterator remove() for both single and multi threaded environments, will I not get any ConcurrentModificationException or some other exception either?

In general, you will, for both single and multi threaded environments, get ConcurrentModificationExceptions.

CMEs can be caused by many things, not just "not using Iterator.remove when iterating over a list using an iterator". For example, here's some code that produces a CME:

List<String> list = new ArrayList<>(List.of("1", "2"));
Iterator<String> iter = list.iterator();
iter.next();
list.add(0, "first!"); // adding to the list while iterating over it
iter.remove(); // we're using Iterator.remove here, still CME!

Also,

List<String> list = new ArrayList<>(List.of("1", "2"));
// make two iterators of the same list
Iterator<String> iter1 = list.iterator();
Iterator<String> iter2 = list.iterator();
iter1.next(); // advance one of them
iter1.remove(); // we're using Iterator.remove here
iter2.next(); // iter2 doesn't know about iter1 has removed an element, so CME

Something like that happened in the question: Why does this Java code trigger a ConcurrentModificationException? which I have answered.

In your code though, I don't see such things happening, so I think it should be fine in a single thread.

If the list is accessible by multiple threads, however, then you have problems. Iterator.remove is not supposed to solve all your multithreading synchronisation issues for you. Another thread could do any structural change to the list while you are iterating over it, if you don't do proper synchronisation, that is. One way (there are definitely better ways depending on your use case) to solve this would be to acquire a lock before doing any structural changes to the list, and before the iteration.

The standard library provides a bunch of thread-safe collections. Choose the appropriate one if you need.

Upvotes: 4

Related Questions