java - 并发修改异常——设置数组元素

标签 java arrays recursion arraylist concurrentmodification

我在 JAVAdocs 中读到,当您在迭代列表时对列表进行结构修改时,会出现并发修改异常。在我的例子中,我没有更改数组的大小,而是只是替换了数组中的一些索引。尝试了很多东西,但这似乎不起作用。

提供下面的代码片段。(该代码是解决 n 皇后问题的递归函数)

    public ArrayList<ArrayList<String>> solve(int a, String[] arr,int beg,
ArrayList<ArrayList<String>> result) {      
    for( int i=beg;i< a*a ;i++){
        String s = arr[i];
        if(s.equals(".")){
            //fill Q and look for valid combs
           arr[i] = "Q";
           if(i== (a*a)-1){
                 String[] t = (String[])(arr.clone());
                 result.add(new ArrayList<String>(Arrays.asList(t)));
           }else{
               ArrayList<Integer> filled = fillX(arr,i,a,"x");//this function fills "X" in queen's path and returns the filled indices

               ArrayList<ArrayList<String>> tmp = solve(a,arr,i+1,result);
               if(!tmp.isEmpty()){
                    for(ArrayList<String> t :tmp){
                        result.add((ArrayList<String>)t.clone());
                     }
               }
                for(int x = 0;x< a*a;x++){                      
                    if(filled.contains(x)){
                        arr[x] = ".";//the exception goes away on removing this line
                    }                         
                }                 
           }
           arr[i] =".";
        }
    }
        return result;  
}

堆栈跟踪--

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Solution.solve(Solution.java:29)
at Solution.solveNQueens(Solution.java:7)
at Main.main(Main.java:323)

最佳答案

我相信您遇到了典型的并发修改场景。

ArrayList<ArrayList<String>> tmp = solve(a, arr, i + 1, result);
for (ArrayList<String> t : tmp) { // <-- iterating through the result of a recursive call.
    result.add((ArrayList<String>)t.clone());
}
...
return result; // <-- while the recursive call returns the `result` argument.

它基本上是在做类似的事情:

for (ArrayList<String> t : result) {
    result.add((ArrayList<String>)t.clone());
}

恕我直言,您可以将 resolve 设为 void 方法,并将结果直接添加到传入的结果参数中;或者您可以删除结果参数并使每个递归调用创建一个本地列表并返回它。

关于java - 并发修改异常——设置数组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37913721/

相关文章:

java - hibernate递归Json响应

java - 搜索数组的递归方法不起作用

java - 为什么Android中只能UI线程更新UI?

JavaFX DatePicker - 删除文本框

java - JSF转换器全局解决方案

java - 使用 Criteria API 通过 Hibernate 选择没有父级的记录

将莫尔斯字符串转换为字符数组

python - 超出 Django 最大递归深度

javascript - 如何检查一个单词是否由不同数组中的字母组成

c++返回和使用char数组指针