Java ArrayList元素被Last Added Element覆盖

时间:2016-06-21 18:42:39

标签: java arrays

我试图编写一个可以通过他的经验学习的算法(在游戏中连接四个)。为此,我想保存List中的所有单个步骤。但是如果我将元素添加到我的列表中,列表中的每个元素都会被我添加的元素覆盖。我不知道为什么会这样,甚至在1Hour搜索之后我也不知道为什么,因为我的Runde.java中没有静态字段。代码在这里:(我是德国人,所以不要为那些奇怪的变量名称而感到惊讶)

package me;

public class Runde{

    private int[][] spielfeld;
    private int[][] x= new int[7][5];
    private int lastx;
    private int lasty;
    public Runde(int[][] spielfeld1, int xi, int jetzgzuege, int y){
        spielfeld=spielfeld1;

        lastx=xi;
        x[xi][4]=jetzgzuege;
        lasty=y;
    }
    public boolean equal(int[][] spielfeld){
        if(spielfeld.equals(spielfeld)){
            return true;
        }else{
            return false;
        }
    }
    public void finishround(boolean sieg, int geszuege){
        x[lastx][0]+=1;
        if(sieg){
            x[lastx][1]+=1;
            x[lastx][2]+=geszuege;
        }else{
            x[lastx][3]+=geszuege;
        }

    }
    public int[][] getSpielfeld(){
        return spielfeld;
    }
    public int[][] getData(){
        return x;
    }
    public int getlastx(){
        return lastx;
    }
    public int getlasty(){
        return lasty;
    }
}


static ArrayList<Runde> liste= new ArrayList<Runde>();
static ArrayList<Runde> Steps= new ArrayList<Runde>();


static void erzeugeGen(){
    int[][] spielfeld=leeresSperzeugen();
    int x=0;
    int y=0;
    int zug=0;
    int rand = new Random().nextInt(2);
    boolean player;
    if(rand==1){
     player = true;
    }else{
     player=false;
    }
    while(!winner(spielfeld,x,y) && zug<42){
        zug++;
        player=!player;
        Runde r;
        if(player){
                r= Computerzug(spielfeld.clone(),1,zug); // If i have a look in to the spielfeld in this element, its fine
                Steps.add(r); // But after adding like this, its overridden :(
        }else{
                r= Computerzug(spielfeld.clone(),2,zug);
        }
        x=r.getlastx();
        y=r.getlasty();
        if(player){
            spielfeld[y][x]=1;
        }else{
            spielfeld[y][x]=2;
        }
    }
    if(zug<42){
    GenAuswerten(zug,player);
    zuege+=zug;
    }else{
        gen--;
    }

}

static void GenAuswerten(int zug, boolean win){
    for(Runde r: Steps){
        r.finishround(win, zug);
        ArrayList<Runde> removal = new ArrayList<Runde>();
        for(Runde r2 : liste){
            if(r2.equal(r.getSpielfeld())){
                removal.add(r2);
            }
        }
        for(Runde r3: removal){
            liste.remove(r3);
        }
    }

  for(Runde r: Steps){
        liste.add(0,r);
    }
  Steps.clear();
}

1 个答案:

答案 0 :(得分:0)

克隆此

时需要克隆二级数组
  

r = Computerzug(spielfeld.clone(),1,zug);

所以正确的代码是

 int spielfeldclone[][] = new int[spielfeld.length][];
 int i = 0;
 for(int[] spielfeldArray: spielfeld){
      spielfeldclone[i] =spielfeldArray.clone()lone();
      i++;
}
r= Computerzug(spielfeldclone,1,zug);

原因是你正在做2d数组的浅拷贝

和记住2d数组是一个数组

的数组 如果数组是原始类型,如int

,那么任何数组的正常clone()都可以工作

但是你克隆的数组包含数组

这意味着您将获得对同一第二级数组对象的新引用

所以

  

spielfeld [0] == spielfeld.clone()[0]

     

是真的

因为spielfeld [0]和spielfeld.clone()[0]都指向同一个对象

现在解决我们需要对每个内部数组进行浅层复制,导致深层复制