【问题标题】:Loading all values of 2d array in java在java中加载二维数组的所有值
【发布时间】:2019-03-07 14:27:14
【问题描述】:

我正在尝试创建一个 2d 益智滑块游戏。我创建了自己的名为 gamestate 的对象来存储父游戏状态和新的游戏状态,因为我计划使用 BFS 解决它。示例数组看起来像

int[][] tArr = {{1,5,2},{3,4,0},{6,8,7}};

这意味着

[1, 5, 2, 3, 4, 0, 6、8、7]

为了存储这个状态,我使用了下面的 for 循环,它带来了 indexOutOfBounds exceptions

public class GameState {
public int[][] state; //state of the puzzle
public GameState parent; //parent in the game tree

public GameState() {
    //initialize state to zeros, parent to null
    state = new int[0][0];
    parent = null;
}

public GameState(int[][] state) {
    //initialize this.state to state, parent to null
    this.state = state;

    parent = null;
}

public GameState(int[][] state, GameState parent) {
    //initialize this.state to state, this.parent to parent
    this.state = new int[0][0];
    for (int i = 0; i < 3; i++){
        for (int j = 0; j < 3; j++) {
            this.state[i][j] = state[i][j];
        }
    }

    this.parent = parent;
}

关于如何解决这个问题的任何想法?

【问题讨论】:

  • 在第三个构造函数中,您使用new int[0][0] 初始化state。然后您无法访问数组的任何元素。
  • 附带说明,它不是[1, 5, 2, 3, 4, 0, 6, 8, 7],而是[[1, 5, 2], [3, 4, 0], [6, 8, 7]]。见我的answer

标签: java arrays 2d indexoutofboundsexception


【解决方案1】:
  • 对于GameState() 构造函数(默认构造函数):

将此state = new int[0][0]; 更改为:state = new int[3][3];。这样,您就可以使用 (3)x(3) 个元素的容量来初始化数组。

  • 对于GameState(int[][] state, GameState parent) 构造函数:

将此this.state = new int[0][0]; 更改为this.state = new int[state.length][state.length &gt; 0 ? state[0].length : 0];

这样,你初始化数组的容量为

(state.length)x(state[0].length0 如果state.length0) 元素。

此外,您必须循环直到 state.lengthi 和直到 state[i].lengthj

GameState构造函数中,像这样:

public GameState(int[][] state, GameState parent) {
    //initialize this.state to state, this.parent to parent
    this.state = new int[state.length][state.length > 0 ? state[0].length : 0];
    for (int i = 0; i < state.length; i++){
        for (int j = 0; j < state[i].length; j++) {
            this.state[i][j] = state[i][j];
        }
    }

    this.parent = parent;
}

另外,作为旁注,它不是[1, 5, 2, 3, 4, 0, 6, 8, 7]

但是[[1, 5, 2], [3, 4, 0], [6, 8, 7]].

【讨论】:

    【解决方案2】:

    问题出在初始化部分。

    this.state = new int[0][0];
    

    此代码将创建一个零尺寸二维数组。这就是为什么当您尝试在其中设置值时会出现 indexOutOfBounds 异常。

    如果你想用零初始化你的数组,正确的语法是:

    this.state = {{0,0,0},{0,0,0},{0,0,0}};
    

    请参阅官方文档以获取完整参考: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html

    【讨论】:

    • 我认为this.state = state = new int[3][3]; 是一个更清晰的代码(与this.state = {{0,0,0},{0,0,0},{0,0,0}}; 相同)。但你的也很好。但是请考虑到indexOutOfBounds 没有发生在构造函数GameState() 中,而是发生在这个构造函数中:GameState(int[][] state, GameState parent),您在答案中没有提到。
    • 你是对的,new int[3][3]; 会产生同样的效果(因为原始类型“int”的默认值为 0)。我选择发布“显式”版本,因为我认为它更具教学性。
    • 我没有提到任何构造方法。当然,他必须同时纠正两者。
    【解决方案3】:

    在第三个构造函数中,您使用空数组初始化 this.state。它没有元素,因此长度为0。使用 for 循环访问此数组的任何元素都会产生 ArrayIndexOutOfBoundsException

    由于您将state 作为参数传递,您可能希望将其值复制到字段state

    你可以这样做:

    public GameState(int[][] state, GameState parent) {
        this.state = new int[state.length][];
        for (int i = 0; i < state.length; i++) {
            if (state[i] != null) {
                this.state[i] = Arrays.copyOf(state[i], state[i].length);
            }
        }
    
        this.parent = parent;
    }
    

    您当然可以调用Arrays.of(state),但这不会返回state 的深层副本。对于每个i,您将拥有this.state[i] == state[i]


    延伸阅读:How do I copy a 2 Dimensional array in Java?

    【讨论】:

      猜你喜欢
      • 2021-06-22
      • 2020-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-28
      • 1970-01-01
      相关资源
      最近更新 更多