2016-12-05 73 views
1

我有一个方法,应该创建一个列表Name对象来自一个数据集,其中包含一个名称和11个整数,表示该名称在数十年中的流行度。数据退出for循环后ArrayList值设置为最后一个值

例子:

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

目前的数据集被正确读取,当我检查Name对象从内部for循环的一切是正确的。

但在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; 

} 

如何我从main方法调用:

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[]尝试,但同样的事情发生。

我在做什么错,我该怎么办才能修复错误?

+2

在循环**中创建'int [] popsInts = new int [11];'**。现在,你有一个数组,你多次添加到你的'List'。 –

+0

'Name'的实现是什么? –

+0

@ElliottFrisch工作,但我不明白为什么它的工作。 popInts在每个循环都更改为新值,并且在将每个名称对象添加到打印正确值的ArrayList后打印每个名称对象。如何在循环外部创建int数组对循环退出后发生的情况产生影响,即使循环内部它完美工作?感谢通过这种方式的快速反应:)编辑:杰克在他们的答案解释。 –

回答

3

的问题是,你Name类是可能的东西定义为

class Name { 
    String name; 
    int[] popsInt; 

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

那么,你是里面存储例如Nameint[]参考。但是,你传递给构造函数的数组只是一个,它的构造是分析所有的数据外循环:

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实例都有自己的阵列。

+1

是的,否则,构造函数可以创建数组的副本。 –

+1

@MauricePerry:的确我在答案中指定了_“您必须复制传递的数据..”_ – Jack

+0

好的,对不起。也就是说,我认为构造函数应该总是制作任何想要保留的副本。 –