2011-08-10 90 views
3

所以我在我的代碼中有這個循環,需要兩個單獨工作的迭代器。但是,當它嘗試使用rbIterator.next()時,java會拋出ConcurrentModificationException異常。我如何阻止這種情況發生? 謝謝雙迭代器循環

Iterator<Road> raIterator = roads.listIterator(0); //I also tried .iterator(), with no avail 
while(raIterator.hasNext()){ 
    Road ra = raIterator.next(); 
    Iterator<Road> rbIterator = roads.listIterator(0); 
    while(rbIterator.hasNext()){ 
     Road rb = rbIterator.next(); 
     //snipped code that adds a road to the list 
     roads.add(xyz); 
    } 
} 

回答

6

除非您創建允許它的實現,否則您不能在迭代它們的同時向List的大多數標準實現添加項目!但是,請參見javadoc。 Java集合框架的大部分*(也許都不是全部)也不是實現。

一種解決方案是創建一個新的列表,temp,迭代之前,當你重複元素添加到temp,然後在temp的所有元素添加到第一。

編輯:使用addAll(temp),感謝@邁克爾復活節

List<Road> temp = new ArrayList<Road>(); 

for(Road ra : roads){ 
    for (Road rb : roads){ 
     temp.add(xyz); 
    } 
} 

roads.addAll(temp); 
+3

只是「道路。addAll(temp);「而不是第二個循環 –

0

我以前遇到過這個問題。這是因爲你試圖迭代相同的事物(道路)兩次。這是很危險的,因爲如果一個迭代器修改道路,那麼另一個迭代器將被拋入未知/不可靠狀態。

如果你可以設法使用for循環來解決這個問題,因爲它似乎滿足了需求。這將取決於道路類型(您未包括在內)。

+0

該問題與雙迭代完全無關,只與調用add()有關。 –

+0

它與迭代有關。當你調用add時,你已經修改了正在迭代的列表,所以同樣的事情正在被同時修改,因此是例外。 – hbhakhra

+0

迭代*兩次*與它無關。 –

0

不能使用迭代器。但是,您可以使用List的get()方法直接訪問。

此代碼,你想要做什麼(編譯和運行OK):

for (int i = 0; i < roads.size(); i++) { 
    Road ra = roads.get(i); 
    for (int j = 0; j < roads.size(); j++) { 
     Road rb = roads.get(i); 
     //snipped code that adds a road to the list 
     roads.add(xyz); 
    } 
} 
+0

使用這種方法的問題在於,每次碰到內部循環時,您都會冒險(閱讀:您將會)使用任何新道路,而內部循環很可能不是您想要的。解決這個問題的方法是在開始第一個循環之前設置一個等於'roads.size()'的局部變量,並將其用於內部循環的約束。 – ty1824

1

如果使用ListIterator<E>相反,你就可以添加。您得到異常的原因爲B/C的這(從的javadoc):此類的迭代器並返回

的迭代器的ListIterator 方法是快速失敗的:如果列表在任何 結構修飾除了通過迭代器自己的remove或add方法創建迭代器之外,迭代器將以任何方式拋出 ConcurrentModificationException。

你不能直接修改列表本身,但通過迭代器,你可以。基類Iterator<E>類沒有添加方法,但ListIterator<E>確實如此,這是您在調用obj.listIterator() anywqay時所得到的結果。