如果它在每次迭代后返回到其原始状态,我可以安全地改变我正在迭代的数组吗?

mav*_*vix 9 java loops

我正在为Java中的游戏编写一个minimax算法,并且出于速度目的,当我递归地通过决策树时,改变游戏状态.但是,这涉及修改我迭代的移动列表.

public int minimax(int currentDepth) {
    if (currentDepth == depth || board.legalMoves.isEmpty()) {
        int eval = board.eval();
        board.takeBack(1);
        return eval;
    }
    int x = Integer.MIN_VALUE;
    for (Tuple move : board.legalMoves) {
        board.move(move);
        x = max(x, -1*minimax(currentDepth+1));
        board.takeBack(1);
    }
    return x
}
Run Code Online (Sandbox Code Playgroud)

board.move()方法会改变ArrayList legalMoves,但takeBack(1)会将其恢复到原始状态.这会导致任何问题吗?

NPE*_*NPE 5

总之,是的.

您没有指定类型board.legalMoves.你说它是数组,但它不可能,因为你正在调用isEmpty()它.因此,我怀疑你的意思ArrayList.如果是这种情况,文档很清楚:

这个类iteratorlistIterator方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对列表进行结构修改,除了通过迭代器自己removeadd方法之外,迭代器将抛出一个ConcurrentModificationException.因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未确定时间冒任意,非确定性行为的风险.

我看到两种解决方法:

1)避免结构修改.换句话说,可以更改元素的,但添加/删除元素是不行的.

2)迭代ArrayList使用索引:

for (int i = 0; i < board.legalMoves.size(); i++) {
    Tuple move = board.get(i);
    ...
}
Run Code Online (Sandbox Code Playgroud)