我正在做一个压缩文件的程序(表示为Byte的ArrayList),在某些时候我必须用一个字节(“string”作为一个字节替换所有出现的预定义“字符串”)字节序列,而不是Java语言中的字符串。)
Byte类型ArrayList的“预定义字符串”存储在变量opt_word中,其长度存储在变量opt_length中,并且总是> = 2
我在“HERE”处注明了并发修改例外情况。进一步调试显示,在第一次替换后,循环迭代发生异常。
我知道其他人问过here和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);
}
答案 0 :(得分:3)
这与您链接的其他人的情况相同。 remove()方法更改了Arraylist的大小。迭代时更改Arraylist大小会导致您提到的并发修改错误。解决方案是跟踪要在其他列表中删除的项目,然后在for循环结束后将其删除。
答案 1 :(得分:1)
更新
我尝试做你想做的事情,即搜索和替换,它对我有用。我实现了一个示例代码。看看它是否适合你。
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);
}
}
}