2012-02-23 1 views
1

J'ai deux ArrayLists, chacun contenant des blocs de certaine taille: blockList, eraserList. Les blocs sont des objets avec deux champs: début et fin. J'ai besoin de soustraire un ensemble de blocs de l'autre ensemble de blocs.Problèmes avec ListIterator et l'exception de modification simultanée

Je dois parcourir le eraserList et "effacer" les blocs de la blockList où ils se chevauchent. Ainsi, mon code ressemble à:

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. 
         ... 
        } 
      } 
     } 

Je ne comprends pas pourquoi j'obtiens une exception de modification simultanée. Je ne modifie jamais le eraserList. J'essaye de modifier l'objet de bloc qui est assigné dans le "bloc de bloc = it.next();" déclaration. Je modifie également le blockList en supprimant ou en ajoutant des blocs à la liste. Je pensais que l'intérêt de ListIterator était qu'il vous permettait de modifier, d'ajouter ou de soustraire une liste que vous parcourez. La trace d'échec pointe vers l'effaceur de blocs = it.next(); comme la ligne dessinant l'exception, mais je ne sais pas ce que cela me dit. Est-ce que quelqu'un peut m'aider à comprendre ce que je fais mal?

Merci!

+0

Vous modifiez blockList si ... la seule modification que vous êtes autorisé à faire avec un itérateur est l'appel it.remove(), qui supprime l'élément actuel de la liste. Toute action sur la liste entraînera l'exception de modification simultanée. – pents90

Répondre

4

Oui, ListIterator est conçu pour permettre la modification de la liste. Mais vous n'utilisez pas la méthode remove() de ListIterator, mais manipulez directement la liste sous-jacente elle-même.

+0

La même mise en garde s'applique aux opérations 'add' qui semblent être mises en commentaire. –

+0

Merci. Je suppose que la seule façon d'ajouter de nouveaux éléments à la liste est de les accumuler dans une liste temporaire et de faire un addAll une fois la boucle terminée. – MyTimeFinder

0

Remplacer

blockList.remove(block); 

avec

it.remove(); 

Si vous supprimez un élément d'une autre manière, vous pouvez obtenir une CME.

0

Vous devez appeler remove() sur le Iterator, et non sur le List.

De la javadoc:

Si un seul thread émet une série d'invocations de méthode qui constitue une violation du contrat d'un objet, l'objet peut lancer cette exception . Par exemple, si un thread modifie directement une collection pendant qu'il itère sur la collection avec un itérateur fail-fast, l'itérateur lira cette exception.

Questions connexes