2016-12-05 130 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

好的,對不起。也就是說,我認爲構造函數應該總是製作任何想要保留的副本。 –

相關問題