2009-10-25 81 views
0

下面的代碼改變一個迭代對象的屬性只是產生問題的例子:的Java:在遍歷它

public static void main(String[] args) { 
    Collection<Integer> src = new ArrayList<Integer>(); 
    Collection<Integer> dest = new ArrayList<Integer>(); 

    src.add(2); 
    src.add(7); 
    src.add(3); 
    src.add(2201); 
    src.add(-21); 

    dest.add(10); 

    while (src.size() != 0) { 
    for (int i : dest) { 
    int min = Collections.min(src); 
    dest.add(min); 
    src.remove(min); 
    } 
    } 

} 

我想要做的就是從SRC在到dest移動一切具體的順序。 (在這裏,就是爲最小值,但是這只是從我的真正的問題簡單化。)不過,我修改DEST同時遍歷它,並收到以下錯誤:

Exception in thread "main" java.util.ConcurrentModificationException 
at java.util.AbstractList$Itr.checkForComodification(Unknown Source) 
at java.util.AbstractList$Itr.next(Unknown Source) 
at nth23.experimental.MoveBetweenSets.main(MoveBetweenSets.java:25) 

我怎樣才能解決這個?

+0

基於「我想要做的是從特定的順序移動一切從src到dest」 - 不能你的排序src然後只需添加所有目標? (Collections.sort,Collections.addAll)? –

回答

1

可以在迭代它使用iterator.remove()了從集合(當然,有些收藏)刪除 - 但你通常不能添加到它。

然而,隨着newacct在評論中指出,ListIterator接口包括add方法,所以你應該能夠改變這樣的代碼:

public static void main(String[] args) { 
    Collection<Integer> src = new ArrayList<Integer>(); 
    List<Integer> dest = new ArrayList<Integer>(); 

    src.add(2); 
    src.add(7); 
    src.add(3); 
    src.add(2201); 
    src.add(-21); 

    dest.add(10); 

    while (src.size() != 0) { 
    for (ListIterator<Integer> li = dest.listIterator(); li.hasNext() ;) { 
    int min = Collections.min(src); 
    li.add(min); 
    src.remove(min); 
    } 
    } 
} 

注意,現在dest必須是聲明爲List而不是Collection,並且您需要明確擴展for循環。不過,我仍然不確定爲什麼你首先要重複dest。你在每次迭代中都添加一個元素,所以你永遠不會到達最後。

這是怎麼回事?

while (src.size() != 0) { 
    int min = Collections.min(src); 
    dest.add(min); 
    src.remove(min); 
    } 

或者,正如其他人所說,只需撥打sort() - 通過在一個自定義Comparator如果您需要。

+0

這不是事實。如果您使用ListIterator迭代它們,您可以添加到列表並更改元素。 – newacct

+0

哦,你是絕對正確的。忘記了那位ListIterator。將編輯。 –

0

正如你所看到的,當你迭代它時你不能改變一個集合。 (更確切地說,你可以改變它,但是你不能繼續迭代)

你可以迭代列表的副本或使用傳統的for循環。

無論哪種方式,請確保您完全理解在修改集合時索引發生了什麼;否則,您的代碼將無法正常工作。

如需更具體的建議,請告訴我們您的實際情況。

0

您可以創建臨時列表,以便在不更改dest和src的情況下跟蹤應該添加和刪除的內容。然後,在循環之外使用臨時列表添加和刪除必要的項目。但像Jon Skeet所說,更具體的要求會有所幫助。我認爲有一些限制。

2

是否有一個原因,你不能只是將源列表複製到目的地列表,然後對其進行排序?

 
Collection<Integer> dest = new ArrayList<Integer>(src); 
Collections.sort(dest); 
2

這是一種解決方法:

while (!src.isEmpty()) { 
    int min = Collections.min(src); 
    dest.add(min); 
    src.remove(min); 
} 

但這可能更會使事情變得更糟。更具體一點(正如Jon所說)。

1

說實話,我沒有得到for (int i : dest)部分。如果你刪除它,實際上沒有問題,這回答了這個問題:)