简体   繁体   English

深度复制多维数组

[英]Deep Copy Multidimensional Array

I am creating a new board obtained by exchanging two adjacent blocks in the same row on an original board. 我正在创建一个新板,该板是通过交换原始板上同一行中的两个相邻块获得的。 The problem is that the new board overrides the content of the original board. 问题在于新板将覆盖原始板的内容。

For example: 例如:

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

What happens is that the origBoard becomes the same as the twinBoard when I assert the following: 当我断言以下内容时,发生的事情是origBoard与twinBoard相同:

 Board B = new Board(origBoard);
 Board b = B.twin();
 assertFalse("Calling twin() modifies the original Board.", B.equals(b));

My code is as follows: 我的代码如下:

public class Board {

    private int[][] goalBoard;

    private final Node node;

    private class Node {
        private int[][] board;
        private int move;
        private Node next;
    }

    // construct a board from an N-by-N array of blocks
    // (where blocks[i][j] = block in row i, column j)
    public Board(int[][] blocks) {
        int N = blocks.length;

        goalBoard = new int[N][N];
        for (int i = 0; i < dimension(); i++) {
            for (int j = 0; j < dimension(); j++) {
                if (i == N - 1 && j == N - 1) {
                    goalBoard[i][j] = 0;
                } else {
                    goalBoard[i][j] = N * i + (j + 1);
                }
            }
        }

        // initial node
        node = new Node();
        node.board = blocks;
        node.move = 0;
        node.next = null;
    }

    // board dimension N
    public int dimension() {
        return goalBoard.length;
    }

    // a board obtained by exchanging two adjacent blocks in the same row
    public Board twin() {
        int[][] testBoardATwin = new int[dimension()][dimension()];
        testBoardATwin = node.board;
        int x = node.board[0][0];
        int y = node.board[0][1];

        // DEFAULT
        if (x != 0 && y != 0) {
            testBoardATwin[0][0] = y;
            testBoardATwin[0][1] = x;
        }
        // 2x2
        if (dimension() == 2 || y == 0) {
            if (x == 0 || y == 0) {
                x = node.board[1][0];
                y = node.board[1][1];
                testBoardATwin[1][1] = x;
                testBoardATwin[1][0] = y;
            }
        } else {
            if (x == 0) {
                testBoardATwin[0][1] = node.board[0][2];
                testBoardATwin[0][2] = y;
            }
        }

        Board board = new Board(testBoardATwin);
        return board;
    }

    // does this board equal y?
    public boolean equals(Object y) {
        Board testBoard = (Board) y;
        if (testBoard == null) {
            return false;
        }
        for (int i = 0; i < dimension(); i++) {
            for (int j = 0; j < dimension(); j++) {
                if (testBoard.node.board[i][j] != node.board[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

}

What am i doing wrong? 我究竟做错了什么? Please help. 请帮忙。 Thank you. 谢谢。

int[][] testBoardATwin = new int[dimension()][dimension()];
testBoardATwin = node.board;

This is where your problem is. 这是您的问题所在。 If you want to make a new one, don't follow that up by immediately changing it to the old one. 如果要制作一个new ,不要立即将其更改为旧的。

But the comments are right, too. 但是评论也是正确的。 A straightforward copy and modification would make more sense. 直接复制和修改将更有意义。

This is the problem: 这就是问题:

int[][] testBoardATwin = new int[dimension()][dimension()];
testBoardATwin = node.board;

Everything starts off well when the code makes a new int[][] array, but then it immediately discards that new array and just uses the one belonging to the instance twin is called on. 当代码创建一个新的int [] []数组时,一切都会很好地开始,但是随后它将立即丢弃该新数组,并仅使用属于实例twin那个调用。

Instead, what needs to happen is for node.board to be index by index, or by using something like Arrays.copyOf . 取而代之的是,需要对node.board进行逐个索引或使用Arrays.copyOf类的Arrays.copyOf

node = new Node(); node.board = blocks;

And same tricky place here in Board constructor. 在Board构造函数中还有一个棘手的地方。 You not copying your input array but assigning a reference to a class member property. 您不复制输入数组,而是分配对类成员属性的引用。

In order to deep copy the multi-dimensional array, I did this: 为了深层复制多维数组,我这样做:

  private static int[][] copy2d(int[][] nums) {
            int[][] copy = new int[nums.length][];

            for (int i = 0; i < copy.length; i++) {
                    int[] member = new int[nums[i].length];
                    System.arraycopy(nums[i], 0, member, 0, nums[i].length);
                    copy[i] = member;
            }

            return copy;
        }

    int[][] testBoardATwin = copy2d(node.board);

To make an object you have to follow these instructions: 要创建对象,您必须遵循以下说明:

  • First of all you have to make the class final 首先,您必须使课程最终
  • Make all fields final and private. 使所有字段均为最终字段和私有字段。
  • Don't provide "setter" methods 不要提供“设置”方法
  • Don't allow subclasses to override methods. 不允许子类覆盖方法。
  • Notice that no Methods that modify state 注意,没有修改状态的方法

And One of the best reference you can refer that http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html 最好的参考之一可以参考http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM