Anthony Paliseno
Anthony Paliseno

Reputation: 75

Iterating through a list, while removing from it

So basically here's my issue...I have 2 structures a LinkedList, and a Priority Que(BinaryHeap).

The LinkedList is full of my own objects, and I want to loop through the list, and if a condition is met, remove from the list and put it back into the priority que. Except when I loop when my condition is the size, when I remove, it alters the size, thus never checking my whole list.

goodJobs is a LinkedList. jobList is my currently empty BinaryHeap.

Original idea:

    for (int i = 0; i < goodJobs.size(); i++) {
        if (((Job) goodJobs.get(i)).getArrivalTime() > time) {
            jobList.insert((Comparable) goodJobs.remove(i));
        }

    }

This didn't work for the reason I mentioned above, so instead, i thought of using a sentinel object to detect the end of the list, instead of using the size of the list. Using Java's iterator...

ListIterator i;

int k = 0;
for (i = goodJobs.listIterator(); i.hasNext(); i.next() ) {

    if (((Job) goodJobs.get(k)).getArrivalTime() > time) {
        jobList.insert((Comparable) goodJobs.remove(k));
    }

    k++;
}

I then soon learned that you can't remove from a List while modifying it (removing from it), via ConcurrentModificationException.

Im unsure how to get around the crossroads here. The idea of the method, is that in a BinaryHeap I have a bunch of objects and I want to remove the ones that have a "ArrivalTime" (specified via input file), > the current time of the program.

Here's the whole method itself:

    private LinkedList findCandidates() {

    LinkedList goodJobs = new LinkedList();

    while (!jobList.isEmpty()) {
        goodJobs.add(jobList.deleteMinimum());
    }


    for (int i = 0; i < goodJobs.size(); i++) {
        if (((Job) goodJobs.get(i)).getArrivalTime() > time) {
            jobList.insert((Comparable) goodJobs.remove(i));
        }

    }


    return goodJobs;
}

Upvotes: 4

Views: 102

Answers (2)

kgym
kgym

Reputation: 29

Advice to try to use CopyOnWriteArrayList instead of LinkedList.

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201477

The Iterator.remove() Javadoc says (in part)

The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.

What you should do is get the Iterator and iterate (calling remove() when your condition is met). Something like,

Iterator<Job> iter = goodJobs.iterator();
while (iter.hasNext()) {
    Job j = iter.next();
    if (j.getArrivalTime() > time) {
        jobList.insert(j);
        iter.remove();
    }
}

Upvotes: 4

Related Questions