有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如果在每次迭代后返回到原始状态,java是否可以安全地对正在迭代的数组进行变异?

我正在用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)会将其恢复到原始状态。这会引起什么问题吗


共 (2) 个答案

  1. # 1 楼答案

    是的,你可以,但这很危险。我建议将minmax算法移动到一个新类中,并将要分析的数据传递到构造函数中

    现在,您可以在构造函数中复制数据一次,并且方法可以对该副本进行操作。该算法现在可以以任何方式修改数据,不会影响游戏的其他部分或其他线程。此外,如果您有任何问题,它们必须来自一个类中的代码

    总体目标是为代码的每个修改部分提供一份数据副本,以减少可能导致麻烦的依赖关系

  2. # 2 楼答案

    总之,是的

    您没有指定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);
        ...
    }