2012-02-23 27 views
1

我有兩個ArrayLists,每個都保存一定大小的塊:blockList,eraserList。塊是具有兩個字段的對象:開始和結束。我需要從另一組塊中減去一組塊。ListIterator和併發修改異常的問題

我必須通過eraserList並從塊列表中「擦除」它們重疊的blockList。因此,我的代碼如下所示:

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

我不明白爲什麼我得到併發修改異常。我從不修改eraserList。

我試圖修改在「Block block = it.next();」中分配的塊對象,聲明。我也通過刪除或添加塊列表來修改blockList。我認爲ListIterator的重點在於它允許您修改,添加或減去您正在瀏覽的列表。

Failure Trace指向Blocks橡皮擦= it.next();作爲繪製例外的線條,但我不知道那是告訴我什麼。

任何人都可以幫我弄清楚我做錯了什麼嗎?

謝謝!

+0

雖然你正在修改blockList,但你可以對迭代器進行的唯一修改是調用it.remove(),它從列表中刪除當前項目。列表本身的任何操作都會導致併發修改異常。 – pents90 2012-02-23 21:18:50

回答

4

是的,ListIterator旨在允許修改列表。但是你沒有使用ListIterator的remove()方法,而是直接操作底層列表本身。

+0

同樣的警告適用於似乎被註釋掉的'add'操作。 – 2012-02-23 21:27:19

+0

謝謝。我想將新項目添加到列表的唯一方法是將它們累積在臨時列表中,並在循環完成後執行addAll。 – MyTimeFinder 2012-02-24 01:09:12

0

更換

blockList.remove(block); 

it.remove(); 

如果您刪除元素的另一種方式,你可以得到一個CME。

0

您需要撥打Iterator上的remove(),而不是List

根據JavaDoc:

如果單個線程發出的方法調用序列 違反對象的合同,該對象可能拋出此 例外。例如,如果一個線程直接修改集合 ,而它正在用一個快速迭代器迭代集合,則迭代器將拋出此異常。