提问人:Stelios P.98 提问时间:6/25/2023 最后编辑:Stelios P.98 更新时间:6/28/2023 访问量:93
Java arraylist 不保留我在方法中传递的值
Java arraylist does not keep values that I am passing inside a method
问:
我正在制作一个 AI 游戏,其中 cpu 使用统一成本搜索算法将表中的 N 个编号立方体堆叠成 3 行。我试图做的是该方法,它将返回一个 ArrayList,其中包含给定状态的所有可能移动。generateMoves()
Cube 是一个表示立方体的类,具有自己的 ID(立方体的编号)、X 轴位置和 Y 轴位置。
K 是用户输入
getCubes()
是一个返回表当前状态的方法。ArrayList<Cube>
setCubes()
是一种方法,它接受 并将该列表设置为当前状态。ArrayList<Cube>
isValid()
是一个 Cube 方法,用于检查给定多维数据集是否处于有效位置的 copyOfTable 列表。
isFree()
是一个 Cube 方法,用于检查给定多维数据集是否可以自由移动的 copyOfTable 列表。
public class Table{
private fields
constructor{}
public Arraylist<Table> generateMoves(){
Arraylist<Table> moves = new ArrayList<Table>();
ArrayList<Cube> currentTable = this.getCubes();
ArrayList<Cube> copyOfTable = new ArrayList<Cube>(currentTable);
int X = 1;
int Y = 1;
int K = this.getK();
for(Cube cube : currentTable){
int backupX = cube.getPosX();
int backupY = cube.getPosY();
for(Y = 1; Y <= 3; Y++){
for(X = 1; X <= 4*K; X++){
cube.setPosX(X);
cube.setPosY(Y);
if(cube.isValid(copyOfTable) && cube.isFree(copyOfTable)){
this.setCubes(currentTable);
moves.add(this);
moves.get(0).printTable();
}else{
cube.setPosX(backupX);
cube.setPosY(backupY);
continue;
}
}
}
}
moves.get(anyIndex).printTable();
return moves;
}
}
// main is in a different file
main(){
ArrayList<Table> moves = new ArrayList<Table>();
Table table = new Table();
moves = table.generateMoves();
}
我想要的是在 arraylist 中添加板的当前状态,以便我可以返回给定表可能生成的所有表(状态)。moves.add(this)
moves
问题在于第一个(在第三个 for 循环中)打印了可以生成的每个状态。不仅是我要求的第一个。printTable()
第二个(在 return 语句上方),无论索引如何,都只打印表的第一个状态。printTable()
我在这里错过了什么?
我尝试了上面的代码
答:
"...我在这里错过了什么?..."
您的代码是正确的,您只是误解了 generateMoves 方法的上下文。
对于每次调用,返回的 ArrayList 不会保留,每次调用都会有一个新的 ArrayList。
这种类型的方法需要放在不同的类中。 其中,您可以利用 ArrayList 类字段来填充列表。
请考虑以下几点。
通过将 Table 对象传递给 generateMoves,可以填充类字段移动。
class TableUtil {
static ArrayList<Table> moves = new ArrayList<>();
static ArrayList<Table> getMoves() {
return moves;
}
static void generateMoves(Table table) {
ArrayList<Cube> currentTable = table.getCubes();
ArrayList<Cube> copyOfTable = new ArrayList<Cube>(currentTable);
int X = 1;
int Y = 1;
int K = table.getK();
for(Cube cube : currentTable){
int backupX = cube.getPosX();
int backupY = cube.getPosY();
for(Y = 1; Y <= 3; Y++){
for(X = 1; X <= 4*K; X++){
cube.setPosX(X);
cube.setPosY(Y);
if(cube.isValid(copyOfTable) && cube.isFree(copyOfTable)){
table.setCubes(currentTable);
moves.add(table);
moves.get(0).printTable();
}else{
cube.setPosX(backupX);
cube.setPosY(backupY);
continue;
}
}
}
}
moves.get(table.anyIndex).printTable();
}
}
创建 Table 对象,然后为每个实例调用 generateMoves 方法。
例如
Table tableA = new Table();
Table tableB = new Table();
Table tableC = new Table();
TableUtil.generateMoves(tableA);
TableUtil.generateMoves(tableB);
TableUtil.generateMoves(tableC);
ArrayList<Table> moves = TableUtil.getMoves();
评论
static ArrayList moves
generateMoves
我不知道为什么(请有人向我解释一下),但是在我花了很长时间的反复试验之后,解决方案是制作一种方法来创建有问题的 ArrayList 的“深度”副本,如下所示:
private ArrayList<Cube> createCopyOfTable(ArrayList<Cube> toCopy){
ArrayList<Cube> copy = new ArrayList<>();
for(Cube cube : toCopy){
Cube _cube = new Cube(cube.getID(), cube.getPosX(), cube.getPosY());
copy.add(_cube);
}
return copy;
}
以及我的方法的更新部分:generateMoves()
.
.
.
for(X = 1; X <= 4*K; X++){
cube.setPosX(X);
cube.setPosY(Y);
ArrayList<Cube> copyOfTable = createCopyOfTable(currentTable);
if(cube.isValid(copyOfTable) && cube.isFree(copyOfTable)){
Table table = new Table(K);
table.setCubes(copyOfTable);
this.moves.add(table);
}else{
cube.setPosX(backupX);
cube.setPosY(backupY);
continue;
}
}
.
.
.
评论
this
不引用任何持久状态,而仅引用对正在使用的 Table 实例的引用。new
moves