ArrayList 对象消失 [英] Objects disappearing of ArrayList

查看:29
本文介绍了ArrayList 对象消失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含这些私有成员的类:

I have a class with these private members:

private ArrayList<ArrayList<ArrayList<CustomStuff>>> listOfPaths;
private int currentIndex;

我用这样的方法填充数组:

I fill the array in a method like this:

listOfPaths.get(currentIndex).add(path); //path is ArrayList<CustomStuff>

到目前为止一切都很好.
检查:

All is fine so far.
Checking:

System.out.println(listOfPaths.get(currentIdx).get(listOfPaths.get(currentIdx).size() - 1).size());

给出合适的尺寸.

现在:方法完成后.ArrayList>>

所以 System.out.println(listOfPaths.get(anyValidIdx).get(anyValidIdx).size()); 将永远是 1!

So System.out.println(listOfPaths.get(anyValidIdx).get(anyValidIdx).size()); will always be 1!

顺便说一句:listOfPaths.size()listOfPaths.get(anyValidIdx).size() 给出正确的尺寸!

By the way: listOfPaths.size() and listOfPaths.get(anyValidIdx).size() give the right sizes!

所以只有数组的第三维似乎缩小为单个对象.

So only the third dimension of the array seem to shrink to a single object.

出了什么问题?

背景故事:我在矩阵上有点.开始和结束标记.在这些标记之间我有路径.路径由步骤组成.所以:
- 路径是 ArrayList.
- 相同开始/结束标记的不同路径的集合是:ArrayList>.
- 矩阵上的所有集合都是ArrayList>>.

Background Story: I have points on a matrix. Start and end marks. Between those marks I have paths. A path consists of steps. so:
- A path is ArrayList<Step>.
- Collection of different paths for the same start/end marks is: ArrayList<ArrayList<Step>>.
- All collections on the matrix is ArrayList<ArrayList<ArrayList<Step>>>.

我从一对标记开始,寻找所有可用的路径.搜索时,我添加每个找到的路径:listPaths.get(currentIndex).add(pathBetweenStartAndEnd)
因此,当我完成获取一对标记的路径时,我会增加 currentIndex 并移动到下一对标记,依此类推...

I start with a pair of marks, and look for all the available paths. When searching I add every found path: listPaths.get(currentIndex).add(pathBetweenStartAndEnd)
So when I am finished fetching paths for a pair of marks, I increment the currentIndex and move to the next pair of marks and so on...

完整代码:

import java.util.ArrayList;

public class Solver {

    protected GameBoard board;

    private static ArrayList<ArrayList<ArrayList<BoardCell>>> listOfPaths;
    private int currentPair;

    public GameBoard getSolvedBoard() {
        solve();
        return board;
    }

    public void setBoard(GameBoard board) {
        this.board = board;
    }

    public Solver(GameBoard board)
    {
        super();

        this.board = board;
    }


    protected void solve()
    {
        listOfPaths = new ArrayList<ArrayList<ArrayList<BoardCell>>>();
        currentPair = 0;

        for(CellPair pair : board.getPairs())
        {
            System.out.printf("Getting paths for %d:\n", pair.getFirstCell().getValue());

            ArrayList<BoardCell> path = new ArrayList<BoardCell>();
            path.add(pair.getFirstCell());

            listOfPaths.add(new ArrayList<ArrayList<BoardCell>>());

            DFS(pair.getFirstCell(), pair.getSecondCell(), new ArrayList<BoardCell>(), path);

            System.out.println("--------------------------------------------------");

            ++currentPair;
        }

        System.out.println(listOfPaths.get(0).get(0).size());
        //System.out.println(listOfPaths.get(2).get(205).get(1));
    }

    protected static ArrayList<BoardCell> getSonsForCellOnBoard(BoardCell cell, GameBoard board)
    {
        int row     = cell.getRow(),
            column  = cell.getColumn();

        ArrayList<BoardCell> neighbors = new ArrayList<BoardCell>();

        if(row > 0)
            neighbors.add(board.getCellAtIndex(row - 1, column));
        if(row < board.getNumberOfRows() - 1)
            neighbors.add(board.getCellAtIndex(row + 1, column));
        if(column > 0)
            neighbors.add(board.getCellAtIndex(row, column - 1));
        if(column < board.getNumberOfColumns() - 1)
            neighbors.add(board.getCellAtIndex(row, column + 1));

        return neighbors;
    }

    private void DFS(   BoardCell source, 
                        BoardCell target, 
                        ArrayList<BoardCell> visited, 
                        ArrayList<BoardCell> path   )
    {
        if(source.getRow() == target.getRow() && source.getColumn() == target.getColumn())
        {
            System.out.printf("PATH: %d: ", path.size());
            System.out.println(path);

            ArrayList<BoardCell> temp = new ArrayList<BoardCell>();
            temp = path;

            listOfPaths.get(currentPair).add(temp);

            System.out.println(listOfPaths.get(currentPair).get(listOfPaths.get(currentPair).size() - 1).size());

            return; 
        }

        for(BoardCell son : Solver.getSonsForCellOnBoard(source, board))
        {
            if(visited.contains(son))
                continue;

            if(son != target &&
                    son.getType() == BoardCell.BoardCellType.BoardCell_AnchorCell)
                continue;

            path.add(son);
            visited.add(son);

            DFS(son, target, visited, path);

            visited.remove(son);
            path.remove(path.size() - 1);
        }
    }
}

推荐答案

在 Java 中,非原始类型(在您的情况下存储在路径中的列表)通过引用而不是通过值传递.

In Java non-primitive types (A list in your case stored in path) are passed by reference rather than by value.

当你打电话时:

DFS(son, target, visited, path);

最终在递归结束时,您将路径存储在 listOfPaths 中.

eventually at the end of the recursion you store path in your listOfPaths.

但是在你做完之后:

visited.remove(son);
path.remove(path.size() - 1);

由于 path 是作为引用传递的,因此对它的任何更改都会影响存储在 listOfPaths 中的那个.

Since path was passed as a reference any change to it will affect the one stored in your listOfPaths.

所以替换这个(顺便说一下,在这种情况下临时是多余的):

So replace this (temp is redundant in this case btw):

ArrayList<BoardCell> temp = new ArrayList<BoardCell>();
temp = path;

listOfPaths.get(currentPair).add(temp);

有了这个(只是复制路径列表):

With this (just copying the path list):

ArrayList<BoardCell> temp = new ArrayList<BoardCell>(); 
for (BoardCell bc : path)   
     temp.add(bc);

listOfPaths.get(currentPair).add(temp);

并在您的代码中寻找更多有类似问题的地方.

And look for more places in your code with this similar issue.

这篇关于ArrayList 对象消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆