HiveBrain v1.2.0
Get Started
← Back to all entries
debugjavaMinor

Delay to avoid cocurrent modification

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
modificationcocurrentdelayavoid

Problem

I was attempting to remove items from an ArrayList while iterating through it, only to find out that Java doesn't like that. So I quickly wrote up a Delay that I could pass operations to so I could run them later.

import java.util.HashSet;
import java.util.Set;

public class Delay {
    private Set tasks = new HashSet();

    public Delay(){}
    public Delay(Runnable... tasks){
        for(Runnable task : tasks) this.tasks.add(task);
    }

    public void add(Runnable task){
        this.tasks.add(task);
    }
    public void run(){
        for(Runnable task : tasks) task.run();
        tasks.clear();
    }
}


Code in use (in a card game):

Delay delay = new Delay();

...

// if a hand has no cards, remove it from play
for(Hand hand : hands) if(hand.size() == 0) delay.add(() -> hands.remove(hand));
delay.run();


Is there a flaw in my solution? Or does Java already have a method of handling this, making my code redundant? Any points of improvement?

Solution

Yes java already has that. What you're looking for is an Iterator:

Iterator handIt = hands.iterator();
while (it.hasNext()) {
    Hand current = handIt.next();
    if (current.size() == 0) {
        handIt.remove();
    }
}


This can be simplified / changed to:

for (Iterator handIt = hands.iterator(); handIt.hasNext(); ) {
    Hand current = handIt.next();
    // ...
}

Code Snippets

Iterator<Hand> handIt = hands.iterator();
while (it.hasNext()) {
    Hand current = handIt.next();
    if (current.size() == 0) {
        handIt.remove();
    }
}
for (Iterator<Hand> handIt = hands.iterator(); handIt.hasNext(); ) {
    Hand current = handIt.next();
    // ...
}

Context

StackExchange Code Review Q#105948, answer score: 4

Revisions (0)

No revisions yet.