5

I have two ArrayLists, each holding blocks of certain size: blockList, eraserList. Blocks are objects with two fields: start and end. I need to subtract one set of blocks from the other set of blocks.

I must walk through the eraserList and "erase" blocks out of the blockList where they overlap. Thus my code looks like:

 void eraseBlocks (Arrylist<Blocks> blockList, ArrayList<Blocks> eraserList) {
    ListIterator<Blocks> it = blockList.listIterator();

    for (Blocks eraser: eraserList) {
        while (it.hasNext()) {
            Blocks block= it.next();
            if ((eraser.start <= block.start) && (eraser.end >= block.end))
                 blockList.remove(block);
            else if ((eraser.start <= block.start) && (eraser.end < block.end)){
                 block.set(start, eraser.end);
            else if () {
                        ...
                 //more code for where the eraser partially erases the beginning, end, or splits the block
                 //if statements call the .add(), .set(), and remove() methods on the blockList.
                        ...
                  }
            }
        }

I don't understand why I am getting a Concurrent Modification Exception. I never modify the eraserList.

I am trying to modify the block object that is assigned in the "Block block = it.next();" statement. I am also modifying the blockList by removing or adding blocks to the list. I thought the whole point of the ListIterator was that it allowed you to modify, add, or subtract a list you are walking through.

The Failure Trace points to the Blocks eraser = it.next(); as the line drawing the exception, but I don't know what that is telling me.

Can anyone help me figure out what I am doing wrong?

Thanks!

SBI
  • 2,322
  • 1
  • 17
  • 17
MyTimeFinder
  • 1,787
  • 4
  • 23
  • 28
  • 1
    You are modifying blockList though... the only modification you are allowed to do with an iterator is call it.remove(), which removes the current item from the list. Any action on the list itself will cause the concurrent modification exception. – pents90 Feb 23 '12 at 21:18

3 Answers3

8

Yes, ListIterator is designed to allow the modification of the list. But you are not using the remove() method of the ListIterator, but directly manipulate the underlying list itself.

Jan
  • 2,498
  • 1
  • 15
  • 6
0

Replace

blockList.remove(block);

with

it.remove();

If you remove an element another way, you can get a CME.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

You need to call remove() on the Iterator, not on the List.

From the javadoc:

If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will thow this exception.

DNA
  • 42,007
  • 12
  • 107
  • 146