递归中的java.util.ConcurrentModificationException

时间:2016-12-02 13:45:27

标签: java recursion

我知道调试后儿子列表被更改了 我不知道为什么会改变 这个修改导致我的算法出现问题

public class IDS extends Algo {
public State found = null;

public IDS(char[][] input, int size) {
    super(input, size);
}

public String solve() {
    State root = new State(0, 0, 0, 0, "", 0, 0);
    for (int i = 0; i < size * size; i++) {
        found = DLS(root, i);
        if (found != null) {
            return found.path + " " + found.dist;
        }
    }
    return "no path";
}

private State DLS(State node, int depth) {
    if (depth == 0 && super.inp[node.row][node.col] == 'G') {
        return node;
    }
    if (depth > 0) {
        // List<State> sons = super.find_neighbors(node.row, node.col, node.prod_time);
        // for (int j = 0; j < sons.size(); j++) {
        //State cur = sons.get(j);
        for(State cur : super.find_neighbors(node.row, node.col, node.prod_time)){
            cur.addCost(node.dist);
            cur.path = cur.addpath(node.path);
            found = DLS(cur, depth - 1);
            if (found != null) {
                return found;
            }
        }
    }
    return null;
}

}

这是抽象类:

abstract class Algo {
public static Map<Integer,String> ways = new TreeMap<>();
protected char[][]inp;
protected int size;
private Map<Character,Integer>costs = new HashMap<>();
public List<State>sons = new ArrayList<>();

public Algo(){}
public Algo(char[][] input,int size){
   inp = input;
    this.size = size;
    ways.put(1,"R");
    ways.put(2,"RD");
    ways.put(3,"D");
    ways.put(4,"LD");
    ways.put(5,"L");
    ways.put(6,"LU");
    ways.put(7,"U");
    ways.put(8,"RU");
    costs.put('R',1);
    costs.put('D',3);
    costs.put('H',10);
    costs.put('G',0);
    costs.put('S',0);
}
private void addDirection(int row,int col,int prod, int loc){
    int cos = costs.get(inp[row][col]);
    State s = new State(row,col,0,prod,"",loc,cos);
    sons.add(s);
}
public abstract String solve();
//gets the parent i,j and the prod_t of the sons
public List<State> find_neighbors(int i, int j,int prod_t){
    List<String>openD = new ArrayList<>();
    sons.clear();

    if(j+1 < size) {//right
        if (inp[i][j + 1] != 'W') {
            addDirection(i, j + 1, prod_t, 1);
            openD.add("R");
        }
    }
    if(i-1 >= 0) {
        if (inp[i - 1][j] != 'W') {//up
            addDirection(i - 1, j, prod_t, 7);
            openD.add("U");
        }
    }
    if(i+1 < size) {
        if (inp[i + 1][j] != 'W') {//down
            addDirection(i + 1, j, prod_t, 3);
            openD.add("D");
        }
    }
    if(j-1 >= 0){
        if(inp[i][j-1]!='W'){//left
            addDirection(i,j-1,prod_t,5);
            openD.add("L");
        }
    }

    if(openD.contains("L")){
        if(openD.contains("U")){
            if(inp[i-1][j-1]!='W'){
                addDirection(i-1,j-1,prod_t,6);
            }
        }
        if(openD.contains("D")){
            if(inp[i+1][j-1]!='W'){
                addDirection(i+1,j-1,prod_t,4);
            }
        }
    }
    if(openD.contains("R")){
        if(openD.contains("U")) {
            if (inp[i - 1][j + 1] != 'W') {
                addDirection(i - 1, j + 1, prod_t, 8);
            }
        }
        if(openD.contains("D")){
            if(inp[i+1][j+1]!='W'){
                addDirection(i+1,j+1,prod_t,2);
            }
        }
    }
    return sons;
}

}

异常只是帮助我知道列表已经修改但是仍然不知道原因:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at IDS.DLS(IDS.java:33)
at IDS.solve(IDS.java:17)
at ex1.main(ex1.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

2 个答案:

答案 0 :(得分:2)

super.find_neighbors 修改并返回 sons 列表。在循环内部,递归调用方法 DLS ,再次调用 super.find_neighbors (修改当前迭代上面一次递归的相同列表)。因为在迭代过程中更改了列表,所以抛出了异常。

答案 1 :(得分:0)

你在Algo.find_neighbours()里面做了一个sons.clear()这将导致循环中的ConcurrentModification。此外,由于find_neighbours()总是返回一个空列表,那么试图迭代它的是什么?