web-dev-qa-db-ja.com

ループごとに「advanced」を使用してJavaで配列を初期化する

'advanced' forループを使用してJavaで配列を初期化することは可能ですか?

例えば.

    Integer[ ] numbers = new Integer[20];
    int counter = 0;
    for ( Integer i : numbers )
    {
        i = counter++;
    }

    for ( Integer i : numbers )
    {
        System.out.println(i);
    }

これはすべてのnullを出力しますが、それはなぜですか?

21
Corleone

いいえ、配列に割り当てていないため、iという一時変数に割り当てています。アレイは変更を認識しません。

以下に、通常のforループを使用したほぼ同等のコードを示します。これにより、アレイの更新に失敗する理由を簡単に確認できるようになります。

for (int j = 0; j < numbers.length; j++) { 
    Integer i = arr[j]; // i is null here.
    i = counter++; // Assigns to i. Does not assign to the array.
}
27
Mark Byers

出力としてnull値を取得する理由は、配列に値を格納しないためです。

Foreachループを使用して配列を初期化できますが、配列要素を参照するために手動でカウンターを維持する必要があります。

for (Integer i : numbers ){
    numbers[counter] = counter;
    counter++;
}

明らかに、これはforeachループの意図されたユースケースではありません。問題を解決するには、「従来の」forループを使用することをお勧めします。

for (int i = 0; i < numbers.length; i++){
    numbers[i] = i;
}

Arrays.fill(int [] array、int val) を使用して、すべての要素を同じ値で埋めることができることに注意してください。

4
matsev

基本的にいいえ、あなたが望むようではありません。 'advanced' forループでは、非表示のカウンターにアクセスする方法はなく、対応する配列スロットでwriteアクセスを実行する方法もありません。

2
Thomas Pornin

'advanced' for-loopはカウンターを公開しないため、counter++の結果を特定の配列スロットに書き込むことはできません。

あなたのケースは、「高度な」forループが作成されていない場合です。見る:

http://Java.Sun.com/j2se/1.5.0/docs/guide/language/foreach.html

最後の段落を見てください。

1
ryanprayogo

あなたの場合、できません。 For-eachは、基になるコレクションのイテレータを非表示にするため、配列を「初期化」しようとしたときに、現在の「数値」の位置を把握できません。これは、「高度な」ループが作成されていない1つのユースケースです。

0
Romain