2016-12-05 6 views
1

Nameのリストを作成するはずのメソッドがあります。名前を含むデータセットのオブジェクトと、数十年にわたる名前の人気を表す11の整数。データの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 

は、現在のデータセットは、正しく読み込まれ、私はforループ内からNameオブジェクトをチェックしたときにすべてが正しいです。ループの終了後、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; 

} 
私は、メインメソッドから呼び出していますどのように10

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クラスは何かがあなたがint[]Name内部のインスタンスへの参照を格納している

class Name { 
    String name; 
    int[] popsInt; 

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

として定義され、おそらくであるということです。しかし、あなたは、コンストラクタに渡す配列が一つだけあり、それはすべてのデータを解析し、ループの外で構築されます:

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

OK、申し訳ありません。つまり、コンストラクタは、何かを保持したいと思っているものを常にコピーするべきだと私は思う。 –

関連する問題