-2

I've tried to creating ranking from two sorted lists.

 List<Ordered<String>> rankedList = Collections.synchronizedList(WebCBIR.run(queryData, clusters, idf));
 List<Ordered<String>> rankedList2 = Collections.synchronizedList(WebCBIR.run(queryData, clusters));
 LinkedList<Ordered<String>> result = new LinkedList<>();
 Iterator<Ordered<String>> it = rankedList.iterator();
 Iterator<Ordered<String>> it2 = rankedList2.iterator();

 while (it.hasNext() && it2.hasNext())  {

        Ordered<String> o1 = it.next();
        Ordered<String> o2 = it2.next();
        Ordered<String> o = null;
        if(o1.value() > o2.value()){
            o = o1;
            rankedList.remove(o);
            rankedList2.remove(o);
        }
        else{
            o = o2;
            rankedList.remove(o);
            rankedList2.remove(o);

        }
        result.add(o);
}

This code calls java.util.ConcurrentModificationException. How to deal with it?

podludek
  • 279
  • 2
  • 10
  • This exception should have been called `ModificationWhileIteratingException`. Would have save a lot of confusion, since threading concurrency has nothing to do with the error. This is far from the first such question on SO! – yshavit Jun 04 '13 at 17:09

3 Answers3

8

While using iterator don't remove from List, instead use iterator.remove() method

while (it.hasNext() && it2.hasNext())  {

        Ordered<String> o1 = it.next();
        Ordered<String> o2 = it2.next();
        Ordered<String> o = null;
        if(o1.value() > o2.value()){
            o = o1;
            it.remove();
            it2.remove();
        }
        else{
            o = o2;
            it.remove();
            it2.remove();

        }
        result.add(o);
}
sanbhat
  • 17,522
  • 6
  • 48
  • 64
  • This is not logically equivalent to OP's code. OP wants to remove `o` from `it` and `it2`, not each iterator's current element. – Ted Hopp Jun 04 '13 at 17:07
  • True.. I dint pay attention to logic, just wanted to convey that one should use remove method of iterator. Thanks for pointing it out. – sanbhat Jun 04 '13 at 17:11
0

You can't iterate on a Collection and modify it at the same time.

eternay
  • 3,754
  • 2
  • 29
  • 27
0

The only way to modify a collection while iterating through it with an iterator is through the iterator itself. Since you want to modify both collections by removing an element that might not be the current element for one of the iterators, you cannot use Iterator.remove(). I recommend accumulating a set of elements to be removed and then doing it all after the iterations are complete. Since you are already accumulating in result, you can use that:

while (it.hasNext() && it2.hasNext())  {

    Ordered<String> o1 = it.next();
    Ordered<String> o2 = it2.next();
    Ordered<String> o = o1.value() > o2.value() ? o1 : o2;
    result.add(o);
}
rankedList.removeAll(result);
rankedList2.removeAll(result);
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521