对象消失的ArrayList [英] Objects disappearing of 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<ArrayList<ArrayList<CustomStuff>>>
Now: After the method finishes. There is only one object left in every single leaf in the ArrayList<ArrayList<ArrayList<CustomStuff>>>
所以System.out.println(listOfPaths.get(anyValidIdx).get(anyValidIdx).size());
将始终为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<Step>
.
-相同起点/终点标记的不同路径的集合是:ArrayList<ArrayList<Step>>
.
-矩阵上的所有集合都是ArrayList<ArrayList<ArrayList<Step>>>
.
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中,非原始类型(在您的情况下为列表,存储在path中)通过引用而不是通过值传递.
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);
由于路径是作为参考传递的,因此对其进行的任何更改都会影响存储在listOfPaths中的路径.
Since path was passed as a reference any change to it will affect the one stored in your listOfPaths.
因此,替换掉它(在这种情况下,temp是多余的):
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屋!