我这里的 Arraylist 有问题,它覆盖了我添加到 Arraylist 中的最后一个对象(称为 "Queen")
I have a problem with Arraylist here it is overwrite the last object (called "Queen") I add to evreything in Arraylist
public class Queen {
static int QueenPos[];
public int her;
int N;
public Queen() {
}
public Queen(int[] queenPos) {
this.QueenPos=queenPos;
this.her = getHer();
this.N=getQueenPos().length;
}
public static int[] getQueenPos() {
return QueenPos;
}
public static void setQueenPos(int queenPos[]) {
QueenPos = queenPos;
}
在这个函数中,我在 Arraylist 中添加了对象 Queen,但我在 Arraylist 中遇到了覆盖问题
public static ArrayList<Queen> GenarateQueen (Queen q,int col){
ArrayList<Queen> gen=new ArrayList<Queen>() ;
for (int i = 0; i < q.QueenPos.length; i++) {
int g [] = q.getQueenPos();
g[col]=i;
gen.add(i,new Queen(g));
int a[]=gen.get(i).QueenPos;
int r=0;
}
for (int i = 0; i < gen.size(); i++) {
for (int k = 0; k < gen.get(i).QueenPos.length; k++) {
System.out.print(" | "+gen.get(i).QueenPos[k]+" | ");
}
System.out.println();
}
return gen;
}
发生这种覆盖是因为您每次都在 Queen
对象的同一个 QueenPos[]
对象中进行更改。
示例:
First Iteration
:
您在 g[] 中获取了 queenPos[],它是 {0,1,2,0},它已更新为 {0,1,2,0}
Second Iteration
g[] = QueenPos[] = {0,1,2,0} 并且更新为 {1,1,2,0} 。
因为 g[] 引用了 queenpos[],所以无论你在 g[] 中做了什么改变,它们也会反映到 queenPos[](g[] 是 queenPos[] 的浅拷贝)。
因此,在第一次迭代后,您的 queenPos[] 已更改为 {1,1,2,0} ,因为您正在存储 g[]
,它是数组列表中的间接 queenPos[] gen
并更改为 {1,1,2,0} 。因此,此值在数组列表的 0 和 1 索引处更新。
因此,为了解决这个问题,您可以在每个 for
循环迭代中创建此 QueenPos[]
对象的新(深)副本,方法是使用 link
他更新了执行相同操作的代码:
代码:
public static ArrayList<ExpressionTree> GenarateQueen (ExpressionTree q,int col){
ArrayList<ExpressionTree> gen=new ArrayList<ExpressionTree>() ;
for (int i = 0; i < q.QueenPos.length; i++) {
int g[] = new int[q.QueenPos.length];
System.arraycopy(q.QueenPos, 0, g, 0, 4);
g[col]=i;
gen.add(i,new ExpressionTree(g));
int a[]=gen.get(i).QueenPos;
int r=0;
}
for (int i = 0; i < gen.size(); i++) {
for (int k = 0; k < gen.get(i).QueenPos.length; k++) {
System.out.print(" | "+gen.get(i).QueenPos[k]+" | ");
}
System.out.println();
}
return gen;
}
输出
| 0 | | 1 | | 2 | | 0 |
| 1 | | 1 | | 2 | | 0 |
| 2 | | 1 | | 2 | | 0 |
| 3 | | 1 | | 2 | | 0 |
通过这一行 System.arraycopy(q.QueenPos, 0, g, 0, 4);
我每次都从原始 queenPos[]
创建新数组 g
,而不是在同一个 queenPos[]
.
中进行修改
而且,根据评论,您也可以从构造函数中删除 static
字段。 .所以更新后的 Queen 对象应该是:
public class Queen{
int QueenPos[];
int her;
int N;
public ExpressionTree(int[] queenPos) {
this.QueenPos=queenPos;
this.her = getHer();
this.N=getQueenPos().length;
}
public ExpressionTree() {
}
public int getHer() {
return her;
}
public int[] getQueenPos() {
return QueenPos;
}
public void setQueenPos(int queenPos[]) {
QueenPos = queenPos;
}
}
public class Queen {
static int QueenPos[];
public int her;
int N;
public Queen() {
}
public Queen(int[] queenPos) {
this.QueenPos=queenPos;
this.her = getHer();
this.N=getQueenPos().length;
}
public static int[] getQueenPos() {
return QueenPos;
}
public static void setQueenPos(int queenPos[]) {
QueenPos = queenPos;
}
在这个函数中,我在 Arraylist 中添加了对象 Queen,但我在 Arraylist 中遇到了覆盖问题
public static ArrayList<Queen> GenarateQueen (Queen q,int col){
ArrayList<Queen> gen=new ArrayList<Queen>() ;
for (int i = 0; i < q.QueenPos.length; i++) {
int g [] = q.getQueenPos();
g[col]=i;
gen.add(i,new Queen(g));
int a[]=gen.get(i).QueenPos;
int r=0;
}
for (int i = 0; i < gen.size(); i++) {
for (int k = 0; k < gen.get(i).QueenPos.length; k++) {
System.out.print(" | "+gen.get(i).QueenPos[k]+" | ");
}
System.out.println();
}
return gen;
}
发生这种覆盖是因为您每次都在 Queen
对象的同一个 QueenPos[]
对象中进行更改。
示例:
First Iteration
:
您在 g[] 中获取了 queenPos[],它是 {0,1,2,0},它已更新为 {0,1,2,0}
Second Iteration
g[] = QueenPos[] = {0,1,2,0} 并且更新为 {1,1,2,0} 。
因为 g[] 引用了 queenpos[],所以无论你在 g[] 中做了什么改变,它们也会反映到 queenPos[](g[] 是 queenPos[] 的浅拷贝)。
因此,在第一次迭代后,您的 queenPos[] 已更改为 {1,1,2,0} ,因为您正在存储 g[]
,它是数组列表中的间接 queenPos[] gen
并更改为 {1,1,2,0} 。因此,此值在数组列表的 0 和 1 索引处更新。
因此,为了解决这个问题,您可以在每个 for
循环迭代中创建此 QueenPos[]
对象的新(深)副本,方法是使用 link
他更新了执行相同操作的代码:
代码:
public static ArrayList<ExpressionTree> GenarateQueen (ExpressionTree q,int col){
ArrayList<ExpressionTree> gen=new ArrayList<ExpressionTree>() ;
for (int i = 0; i < q.QueenPos.length; i++) {
int g[] = new int[q.QueenPos.length];
System.arraycopy(q.QueenPos, 0, g, 0, 4);
g[col]=i;
gen.add(i,new ExpressionTree(g));
int a[]=gen.get(i).QueenPos;
int r=0;
}
for (int i = 0; i < gen.size(); i++) {
for (int k = 0; k < gen.get(i).QueenPos.length; k++) {
System.out.print(" | "+gen.get(i).QueenPos[k]+" | ");
}
System.out.println();
}
return gen;
}
输出
| 0 | | 1 | | 2 | | 0 |
| 1 | | 1 | | 2 | | 0 |
| 2 | | 1 | | 2 | | 0 |
| 3 | | 1 | | 2 | | 0 |
通过这一行 System.arraycopy(q.QueenPos, 0, g, 0, 4);
我每次都从原始 queenPos[]
创建新数组 g
,而不是在同一个 queenPos[]
.
而且,根据评论,您也可以从构造函数中删除 static
字段。 .所以更新后的 Queen 对象应该是:
public class Queen{
int QueenPos[];
int her;
int N;
public ExpressionTree(int[] queenPos) {
this.QueenPos=queenPos;
this.her = getHer();
this.N=getQueenPos().length;
}
public ExpressionTree() {
}
public int getHer() {
return her;
}
public int[] getQueenPos() {
return QueenPos;
}
public void setQueenPos(int queenPos[]) {
QueenPos = queenPos;
}
}