在递归期间,对象在list.add(对象)之后变形。说明?

时间:2018-04-13 14:42:18

标签: java recursion maze

所以我目前正在处理的任务相当简单。我必须找到每个给定迷宫中给定起点的所有出口并将路径打印到屏幕上。多个出口是可能的。迷宫可能如下所示:

    #####.###
    #.....#.#
    #.#####.#
    #.#.....#
    #.#.###.#
    #.#.#.#.#
    #.....#.#
    #########

正方形是正方形。一个点是一个WhiteSquare,一个hashtag是一个BlackSquare,它们都是Square的子类。 Opening是WhiteSquare的子类。

我的想法是在我当前所在的广场的每个邻居上调用go()。方形go()在黑色方块中没有做任何事情,因此在这方面只有白色方块才有效。每次调用go()时,都会将包含所有先前访问过的方块的列表副本作为参数发送,这样它就不会在前一个邻居上调用go()。这是因为我希望算法也适用于周期性迷宫。一旦我打开一个开口,我就会将路径添加到起始方块的可能出口列表(列表列表)中。这是代码:

public void go(ArrayList<Rute> path, WhiteSquare startSquare) {
    ArrayList<Rute> pathCopy = path;
    pathCopy.add(this);
    if (this instanceof Opening) {
        startSquare.addPossibleExit(pathCopy);
        return;
    }
    for (Square neighbour : this.getNeighbours()) {
        if (!path.contains(neighbour)) {
            neighbour.go(pathCopy, startSquare);
        }
    }
}
找到打开后的

System.out.println(startSquare.exits)将打印正确的路径。一切都很好。但是,如果在找到开口之后还有更多的正方形,那么退出中的正确路径将在列表本身内开始增长,即使在添加之后也是如此。我不懂。例如,如果startRoute在上面的迷宫中是(3,1)(伪代码):

System.out.println(Square.toString() + " go. " + Exits: " + startSquare.getExits())

if (this instanceof Opening) {print("Opening found!")}

将打印出来:

(3, 1) go. Exits: []
(2, 1) go. Exits: []
(1, 1) go. Exits: []
(1, 2) go. Exits: []
(1, 3) go. Exits: []
(1, 4) go. Exits: []
(1, 5) go. Exits: []
(0, 5) go. Exits: []
Opening found!
(4, 1) go. Exits: [[(3, 1), (2, 1), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (0, 5)]]
(5, 1) go. Exits: [[(3, 1), (2, 1), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (0, 5), (4, 1)]]
(6, 1) go. Exits: [[(3, 1), (2, 1), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (0, 5), (4, 1), (5, 1)]]

我无法解释这里发生了什么。我不希望路径在添加到退出后增长。

2 个答案:

答案 0 :(得分:0)

pathCopy不是new ArrayList,而是path的引用,当您添加到pathCopy时,它实际上会添加到path

您可以创建new ArrayList,然后使用.addAll(path)将所有值复制到new ArrayList

Java中的每个变量都是一个指针,除了基本类型,如int,bool。 当您指定“复杂”类型时,它会指定指针而不是值。

可以找到有关参考和价值的说明here

答案 1 :(得分:0)

正如关于arraylist copying的问题中提到的那样,你并没有真正按照作业复制数组。您应该创建一个新数组并复制这些项目。

ArrayList<Rute> pathCopy = new ArrayList<>(path);