我这里的 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;
            } 
}