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

标签 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
}

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

最佳答案

一句话,是的。

您没有指定 board.legalMoves 的类型。你说它是数组,但它不可能,因为你在它上面调用了 isEmpty()。因此,我怀疑您指的是 ArrayList。如果是这样的话,documentation很清楚:

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

我看到了两种解决方法:

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

2) 使用索引遍历 ArrayList:

for (int i = 0; i < board.legalMoves.size(); i++) {
    Tuple move = board.get(i);
    ...
}

关于java - 如果每次迭代后返回到原始状态,我可以安全地改变正在迭代的数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13468922/

相关文章:

Java servlet 访问配置文件

java - MySQL错误: Lock wait timeout exceeded; try restarting transaction Query

java - JGoodies DefaultFormBuilder - 动态添加行

java - 当循环结束时如何获取第一个索引的范围?

python - 来回循环 Python

java - 检查原始数组是否包含另一个数组

java - 下载文件前如何检查我是否已启用 WIFI?

php - mysql select 在 for 循环内时检查 mysql 结果

python - 在通过 for 循环创建内容时检查 csv 文件

javascript - js循环遍历被点击的元素子节点