如何在Java中创建动态2d数组?

如何在Java中创建动态2d数组?,java,arrays,dictionary,arraylist,javafx,Java,Arrays,Dictionary,Arraylist,Javafx,我一直在四处寻找,但我找不到任何解决我问题的方法 我使用此方法为我的游戏创建棋盘: public void createBoard(Canvas canvas) { ROWS_NUM = (int) canvas.getHeight() / rectangleSize; COLS_NUM = (int) canvas.getWidth() / rectangleSize; grid = new Cell[COLS_NUM][ROWS_NUM]; for (int

我一直在四处寻找,但我找不到任何解决我问题的方法

我使用此方法为我的游戏创建棋盘:

public void createBoard(Canvas canvas) {
    ROWS_NUM = (int) canvas.getHeight() / rectangleSize;
    COLS_NUM = (int) canvas.getWidth() / rectangleSize;
    grid = new Cell[COLS_NUM][ROWS_NUM];

    for (int x = 0; x < COLS_NUM; x++) {
        for (int y = 0; y < ROWS_NUM; y++) {
            grid[x][y] = new Cell();
            grid[x][y].setAndUpdateState(false);
        }
    }
}
public void createBoard(画布){
ROWS_NUM=(int)canvas.getHeight()/rectangleSize;
COLS_NUM=(int)canvas.getWidth()/rectangleSize;
网格=新单元格[COLS_NUM][ROWS_NUM];
对于(int x=0;x

问题是每当我添加一个大于
ROWS\u NUM
COLS\u NUM
的值时,我都会得到超出范围的数组索引,这是我应该做的。我想让数组动态化,我想知道我应该怎么做。我需要将数组转换为ArrayList,还是HashMap更好?如果我希望行和列都是动态的,我该怎么做呢

更好的选择是使用Java列表来实现所需的逻辑:

List<List<Cell>> grid = new ArrayList<>();

for (int x = 0; x < COLS_NUM; x++) {
    List<Cell> cells = new ArrayList<>();
    for (int y = 0; y < ROWS_NUM; y++) {
        cells.add(new Cell());
    }
    grid.add(cells);
}

public boolean isAlive(int x, int y) {
    List<Cell> cells = grid.get(x);
    Cell cell = cells.get(y);        
    return cell != null && cell.getState();
}
List grid=new ArrayList();
对于(int x=0;x
更好的选择是使用Java列表来实现所需的逻辑:

List<List<Cell>> grid = new ArrayList<>();

for (int x = 0; x < COLS_NUM; x++) {
    List<Cell> cells = new ArrayList<>();
    for (int y = 0; y < ROWS_NUM; y++) {
        cells.add(new Cell());
    }
    grid.add(cells);
}

public boolean isAlive(int x, int y) {
    List<Cell> cells = grid.get(x);
    Cell cell = cells.get(y);        
    return cell != null && cell.getState();
}
List grid=new ArrayList();
对于(int x=0;x
使用ArayList(ArrayList可以动态更改其大小)

ArrayList grid=new ArrayList();
使用ArayList(ArrayList可以动态更改其大小)

ArrayList grid=new ArrayList();

这并不是那么容易

您当然可以将网格表示为
列表

但是,这不会给您分配给任何旧号码的免费通行证:

  List<String> list = new ArrayList<>();
  list.set(5,"Hello");
如果您想要一个人口稀少但实际上没有边界的“网格”,这将特别有效

还有更多的方法——包括实现自己的数组重新分配算法(毕竟,这就是
ArrayList
中的内容——如果您好奇的话,可以查找并研究它的源代码)


您可能还应该后退一步,询问在初始化网格后为什么以及何时需要更改网格的大小。固定大小数组中的固定大小数组是一个简单的解决方案,如果它大部分时间都有效,那么值得坚持使用。如果大小只是偶尔变化,那么最好创建一个新网格,并在发生这种情况时将旧值复制到其中

  public void setCell(int x, int y, Cell cell) {
     if(x >= this.grid.length || y >= this.grid[0].length) {
          Cell[][] newGrid = createEmptyGrid(x,y);
          copyCells(this.grid,newGrid);
          this.grid = newGrid;
     }
     this.grid[x][y] = cell;
  }

createEmptyGrid()
这里需要决定新的大小——刚好足够容纳
[x][y]
?还是更大的以防万一?正确的做法取决于您更广泛的需求。

这并不那么容易

您当然可以将网格表示为
列表

但是,这不会给您分配给任何旧号码的免费通行证:

  List<String> list = new ArrayList<>();
  list.set(5,"Hello");
如果您想要一个人口稀少但实际上没有边界的“网格”,这将特别有效

还有更多的方法——包括实现自己的数组重新分配算法(毕竟,这就是
ArrayList
中的内容——如果您好奇的话,可以查找并研究它的源代码)


您可能还应该后退一步,询问在初始化网格后为什么以及何时需要更改网格的大小。固定大小数组中的固定大小数组是一个简单的解决方案,如果它大部分时间都有效,那么值得坚持使用。如果大小只是偶尔变化,那么最好创建一个新网格,并在发生这种情况时将旧值复制到其中

  public void setCell(int x, int y, Cell cell) {
     if(x >= this.grid.length || y >= this.grid[0].length) {
          Cell[][] newGrid = createEmptyGrid(x,y);
          copyCells(this.grid,newGrid);
          this.grid = newGrid;
     }
     this.grid[x][y] = cell;
  }
createEmptyGrid()
这里需要决定新的大小——刚好足够容纳
[x][y]
?还是更大的以防万一?正确的做法取决于您更广泛的需求。

您可以使用ArrayList,但要在任何索引处插入而不担心超出范围,您需要使用嵌套映射和特殊的插入或检索方法

Map<Integer, Map<Integer, Cell>> grid = new HashMap<Integer, Map<Integer, Cell>>();

for (int x = 0; x <= COLS_NUM; x++) {
    Map inner = new HashMap<Integer, Cell>();
    for (int y = 0; y < ROWS_NUM; y++) {
        inner.put(y, new Cell());
    }
    grid.put(x, inner);
}
但是,由于您指定希望能够使用任何索引访问单元格而不获取越界异常,因此可以选择使用映射来实现它。

您可以使用ArrayList,但可以在任何索引处插入而不必担心越界,您可能希望使用嵌套映射和特殊方法来插入或检索

Map<Integer, Map<Integer, Cell>> grid = new HashMap<Integer, Map<Integer, Cell>>();

for (int x = 0; x <= COLS_NUM; x++) {
    Map inner = new HashMap<Integer, Cell>();
    for (int y = 0; y < ROWS_NUM; y++) {
        inner.put(y, new Cell());
    }
    grid.put(x, inner);
}

但是,由于您指定希望能够使用任何索引访问单元格而不获得越界异常,因此可以选择使用映射实现它。

数组始终是固定的。要调整它的大小,您需要重新分配它。如果您想要动态的东西,请使用java.util容器,如List。是的,使用ArrayList会是最好的,因此基本上,您将拥有ArrayList中的ArrayList。“如果我希望行和列都是动态的,我该怎么做?”根据调整数组大小的频率,您应该考虑您喜欢哪种类型的列表—LinkedList或ArrayList。前者可以更有效地重新调整大小,但访问其元素需要更多时间。后者的元素访问速度非常快,但更改其大小的成本更高。数组总是固定的。要调整它的大小,您需要重新分配它。如果您想要动态的东西,请使用java.util容器,如List。是的,使用ArrayList最好,因此基本上,您将拥有ArrayList of ArrayList。”如果我希望行和列都是
     public Cell getCell(Map<Integer, Map<Integer, Cell>> grid, int x, int y) {
     try {
         Cell found = grid.get(x).get(y);
         return found;
     } catch (NullPointerException npe) {
         return null;
     }
 }
int ROWS_NUM = (int) canvas.getHeight() / rectangleSize;
int COLS_NUM = (int) canvas.getWidth() / rectangleSize;

List<List<Cell>> array = new ArrayList<List<Cell>>();

for (int x = 0; x < COLS_NUM; x++) {
    List inner = new ArrayList<Cell>();
    for (int y = 0; y < ROWS_NUM; y++) {
        inner.add(new Cell());
    }
    array.add(inner);
}
// Find equivalent of arr[2][3]
Cell found = array.get(2).get(3);