web-dev-qa-db-ja.com

配列でCollections.shuffle()が失敗するのはなぜですか?

コードが機能しないのはなぜですか?

package generatingInitialPopulation;

import Java.util.Arrays;
import Java.util.Collections;

public class TestShuffle {
    public static void main(String[] args) {
        int[] arr = new int[10];

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

        Collections.shuffle(Arrays.asList(arr));

        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

結果は次のとおりです。0123 4 5 6 7 89。

ランダムにシャッフルされたシーケンスを期待していました。

22
Dmitry

Arrays.asList()は、期待どおりにプリミティブ型の配列に適用できません。 _int[]_に適用すると、Arrays.asList()Integersのリストではなく_int[]_ sのリストを生成します。したがって、新しく作成した_int[]_のリストをシャッフルします。

これは、Javaの可変個引数とジェネリックスの微妙な動作です。 Arrays.asList()は次のように宣言されます

_public static <T> List<T> asList(T... a)
_

したがって、いくつかのタイプTのいくつかの引数を取り、これらの引数を含むリストを生成するか、タイプ_T[]_の1つの引数を取り、この配列に基づくリストを返すことができます(これが可変引数の方法です)作業)。

ただし、後者のオプションは、Tが参照型(つまり、intなどのプリミティブ型ではない)の場合にのみ機能します。これは、ジェネリックス(およびTは型パラメーターです)。

したがって、_int[]_を渡すと、T = _int[]_が得られ、コードが期待どおりに機能しません。ただし、参照型の配列(たとえば、_Integer[]_)を渡すと、T = Integerが得られ、すべてが機能します。

_Integer[] arr = new Integer[10]; 

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

Collections.shuffle(Arrays.asList(arr)); 

for (int i = 0; i < arr.length; i++) { 
    System.out.print(arr[i] + " "); 
} 
_
45
axtavt