退出循环

时间:2016-12-05 13:35:29

标签: java arraylist

我有一个方法应该从数据集中创建一个Name对象列表,该数据集包含一个名称和11个整数,表示该名称在几十年内的流行程度。

数据示例:

Zelda 436 420 468 526 789 961 938 0 0 0 0
Zulma 0 0 0 0 0 0 837 0 0 0 0

目前正确读入数据集,当我从for循环中检查Name个对象时,一切都是正确的。

但在for循环退出后,ArrayList中的所有值都与上一个条目具有相同的受欢迎度值,而name值仍然正确。

会发生什么:

Zelda 436 420 468 526 789 961 938 0 0 0 0
Zelda [436, 420, 468, 526, 789, 961, 938, 0, 0, 0, 0]

实际发生的事情:

Zelda 436 420 468 526 789 961 938 0 0 0 0
Zelda [0, 0, 0, 0, 0, 0, 837, 0, 0, 0, 0]

最后一项的数据和输出:

Zulma 0 0 0 0 0 0 837 0 0 0 0
Zulma [0, 0, 0, 0, 0, 0, 837, 0, 0, 0, 0]

代码:

public static ArrayList<Name> createNameArray(String[] data) {

    int nameLength;
    String name;
    String pops;
    ArrayList<Name> names = new ArrayList<Name>();
    int[] popsInts = new int[11];

    for (int i = 0; i < data.length; i++) {

        // Checking data array, no missing data here
        System.out.println(data[i]); //returns correctly
        nameLength = data[i].indexOf(' ');

        name = data[i].substring(0, nameLength);
        pops = data[i].substring(nameLength + 1);

        for (int k = 0; k < 11; k++) {
            popsInts[k] = Integer.parseInt(pops.split(" ")[k]);
        }

        names.add(new Name(name, popsInts));

        // Checking if Name object added to names is correct which it always is
        System.out.println(names.get(i)); //returns correctly


    }

    // If I print out values of the ArrayList here, everything is wrong
    return names;

}

我如何从主要方法调用:

ArrayList<Name> list = createNameArray(data);
// Printing out ArrayList, all values are wrong except last one
// Using a regular for loop produces same results
for(Name n : list) { 
    System.out.println(n);
}

我尝试使用Name[],但同样的事情发生了。

我做错了什么,我该怎么做才能解决错误?

1 个答案:

答案 0 :(得分:3)

问题是您的Name类可能定义为

class Name {
  String name;  
  int[] popsInt;

  Name(String name, int[] popsInt) {
    this.name = name;
    this.popsInt = popsInt)
  }
}

因此,您要在int[]实例内存储对Name的引用。但是传递给构造函数的数组只是一个,它在循环外部构造,用于解析所有数据:

int popsInt = new int[11];
for (each game) {
  popsInt = parse data
  list.add(new Name(name, popsInt));
}

所以你通过将引用始终传递给同一个数组来构造Name,所以最后它们都指向同一组11个值。

您必须复制传递的数据或在每次调用时分配新数组,例如:

for (each game) {
  int[] popsInt = new int[11];
  popsInt = parse data;
  list.add(new Name(name, popsInt));
}

现在每个Name实例都有自己的数组。