簡體   English   中英

Java:替換ArrayList中的模式時,並發修改異常

[英]Java : Concurrent Modification exception when replacing pattern in ArrayList

我正在做一個壓縮文件的程序(表示為Byte的ArrayList),有時我必須將所有出現的預定義“字符串”替換為一個字節(“ string”作為字節序列) ,而不是Java語言中的字符串)。

字節類型ArrayList的“預定義字符串”存儲在變量opt_word中,其長度存儲在變量opt_length中,且始終> = 2

我在標為“ HERE”的地方收到並發修改異常。 進一步的調試表明,在第一次替換之后,循環迭代就發生了異常。

我知道別人問起喜歡類似的問題在這里這里 ,但我的情況跟他們完全不同。 我使用標准的循環。

            CopyOnWriteArrayList<Integer> removal_indexes = new CopyOnWriteArrayList<Integer>();
            for(int j=0, l=0; j <= encoded.get(k).size() - opt_length; ++j, ++l)
            {
                List<Byte> str = encoded.get(k).subList(j, j + opt_length);
                if (str.equals(opt_word))  // <-- here
                {
                    removal_indexes.add(l);
                    j += opt_length - 1;
                }
            }

            for(int l=0; l < removal_indexes.size(); ++l)
            {
                encoded.get(k).set(removal_indexes.get(l), (byte)(lowr + lengths.size()));
                for(int i=1; i < opt_length; ++i)
                    encoded.get(k).remove(removal_indexes.get(l)+1);
            }

這與您鏈接到的其他情況相同。 remove()方法更改Arraylist的大小。 在迭代過程中更改Arraylist大小會導致您提到的並發修改錯誤。 解決方案是跟蹤要在其他列表上刪除的項目,然后在for循環完成后將其刪除。

@David Pitre已經指出了問題。 將ArrayList更改為CopyOnWriteArrayList

更新:

我嘗試做您想做的事,即搜索和替換,它對我有用。 我實現了一個示例代碼。 看看是否適合您。

public class Search {
List<Byte> fileToCompress;  // Your File
List<Byte> opt_word = new ArrayList<Byte>(); // "String" to search for in the "fileToCompress"
Byte replacement; // Replacement for "String"

public static void main(String args[]) {
    Search s = new Search();

    s.display();
    s.findAndReplace();
    System.out.println("_____________________");
    s.display();
}

public Search() {
    fileToCompress = new CopyOnWriteArrayList<Byte>();

    fileToCompress.add((byte)1);
    fileToCompress.add((byte)3);
    fileToCompress.add((byte)3);
    fileToCompress.add((byte)4);
    fileToCompress.add((byte)5);
    fileToCompress.add((byte)3);
    fileToCompress.add((byte)4);
    fileToCompress.add((byte)6);

    opt_word = new ArrayList<Byte>();

    opt_word.add((byte)3);
    opt_word.add((byte)4);

    replacement = new Byte((byte)0);
}

public void findAndReplace() {
    for(int i=0; i<fileToCompress.size(); i++) {
        boolean isFound = false;
        if(fileToCompress.get(i).equals(opt_word.get(0))) {
            isFound = checkMatch(i);
            if(isFound) {
                replace(i);
            }
        }
    }
}

private boolean checkMatch(int index) {
    boolean isFound = true;
    for(int i=0; i<opt_word.size(); i++) {
        if(!opt_word.get(i).equals(fileToCompress.get(index + i))) {
            isFound = false;
            break;
        }
    }
    return isFound;
}

private void replace(int index) {
    for(int i=0 ; i<opt_word.size(); i++) {
        fileToCompress.remove(index);
    }

    fileToCompress.add(index, replacement);
}

public void display() {
    for(Byte b : fileToCompress) {
        System.out.println(b);
    }
}
}

暫無
暫無

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

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