簡體   English   中英

Java-解析具有2個迭代器和可怕的ConcurrentModificationException的ArrayList

[英]Java - Parsing ArrayList with 2 iterators and the dreaded ConcurrentModificationException

我正在搜索ArrayList並與2個迭代器進行比較。 我正在將值寫到String緩沖區,該緩沖區最終將是XML輸出。 當我解析這些值時,我正在檢查匹配的itemIds。 火柴通常是零件和圖紙。 一個零件可以有很多圖紙。 對於我的XML,我必須知道所有匹配項的類型和名稱,並將值附加在一起。

使用此ArrayList:

itemId類型名稱

1000零件錘
1001部分指甲
1000 dwg語義
1002尺子

我的樣本XML輸出大致如下所示:

<Master itemId=1000 type=part name=hammer>
  <Extra type=dwg name=semantic>
</Master>
<Master itemId=1001 type=part name=nail>
</Master>
<Master itemId=1002 type=part name=ruler>
</Master>

這是我的第一個循環

while (theBaseInterator.hasNext()){
     ImportedTableObjects next = theBaseInterator.next(); 
     currentEntry = next.identiferId;
     currentType = next.typeId;
     currentDatasetName = next.nameId;
     compareInterator = tArray.listIterator(theBaseInterator.nextIndex());
     compareEntriesofArray(currentEntry, currentType, currentDatasetName, compareInterator); <======= calling method for 2nd loop and compare check
  }

我為第二個循環編寫了一個方法並進行比較

private void compareEntriesofArray(Object currentEntry, Object currentType, Object currentDatasetName, ListIterator<ImportedTableObjects> compareInterator)
object nextEntry;   
while (compareInterator.hasNext()) {
    ImportedTableObjects next = compareInterator.next();
    nextEntry = next.identiferId;
    if(nextEntry.equals(currentEntry)) { 
    compareInterator.remove();
    }   

當找到匹配項時,我正嘗試從列表中刪除匹配項。 無需重新檢查已匹配的條目。 因此,當第一個循環繼續在列表中向下移動時-不必再次檢查該條目。

但是當然我得到了ConcurrentModificationException。 我完全理解為什么。 有沒有一種方法可以代替嘗試刪除該條目,而是可以用布爾值或其他方式標記它,因此當第一個循環到達列表中的該條目時,它知道將其跳過並轉到下一個?

將要刪除的所有元素添加到新列表中。

迭代后,調用:

coll1.removeAll (coll2);

不是使用迭代器及其hasNext / next,而是使用列表,您可以從上到下使用for循環進行迭代。 刪除元素(7)之前訪問元素(6)等等對我來說從來都不是問題,但我還沒有看到有人推薦它。

這里完整的代碼

import java.util.*;

public class GuessGame 
{
    public static void main ( String [] args )
    {
        char [] ca = "This is a test!".toCharArray ();
        List <Character> ls = new ArrayList <Character> ();
        for (char c: ca)
            ls.add (c);

        show (ls);
        // first method: remove from top/end and step backwise:
        for (int i = ls.size () - 1; i >= 0; --i)
        {
            char c = ls.get (i); 
            if (c == 'i' || c == 'a' || c == 'e')
                ls.remove (i); 
        }
        show (ls);

        // second approach: collect elements to remove ...
        ls = new ArrayList <Character> ();
        for (char c: ca)
            ls.add (c);
        show (ls);
        // ... in a separate list and 
        List <Character> toRemove = new ArrayList <Character> ();
        for (char c: ls)
        {
            if (c == 'i' || c == 'a' || c == 'e')
                toRemove.add (c); 
        }
        // ... remove them all in one go:
        ls.removeAll (toRemove);
        show (ls);
    }

    private static void show (List <Character> ls)
    {
        for (char c: ls)
            System.out.print (c + " ");
        System.out.println ();
    }   
}

輸出:

T h i s   i s   a   t e s t ! 
T h s   s     t s t ! 
T h i s   i s   a   t e s t ! 
T h s   s     t s t ! 

最簡單的方法可能是創建另一個列表,在該列表中放置“匹配的”條目,然后對照該列表進行檢查。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM