Javaで配列をシャッフルするサンプルです。
Listをシャッフルする
Javaで、List
内部の要素をシャッフル(ランダムに入れ替え)するには、
Java標準で用意されている Collections.shuffle
のAPIを利用すればよいです。
コードサンプル
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class ShuffleListSample { public static void main(String[] args) { List<Integer> targetList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9)); // シャッフルする前 printArray(targetList, "No Shuffle"); // シャッフル1回目 Collections.shuffle(targetList); printArray(targetList, "Shuffle 1 "); // シャッフル2回目 Collections.shuffle(targetList); printArray(targetList, "Shuffle 2 "); // シャッフル3回目 Collections.shuffle(targetList); printArray(targetList, "Shuffle 3 "); } private static void printArray(List<Integer> list, String headerComment) { System.out.printf("%s -> %s\n\n", headerComment, list); } }
実行結果
No Shuffle -> [1, 2, 3, 4, 5, 6, 7, 8, 9] Shuffle 1 -> [6, 7, 1, 5, 8, 3, 2, 4, 9] Shuffle 2 -> [5, 2, 9, 3, 1, 7, 4, 6, 8] Shuffle 3 -> [4, 1, 7, 2, 8, 6, 5, 3, 9]
配列をシャッフルする場合
List
の場合は、標準でシャッフルするAPIが用意されていますが、配列の場合そのようなAPIが用意されていません。
以下のようなメソッドを用意しましょう。(以下はint配列用です)
public static void shuffle(int[] array) { // 配列が空か1要素ならシャッフルしようがないので、そのままreturn if (array.length <= 1) { return; } // Fisher–Yates shuffle Random rnd = ThreadLocalRandom.current(); for (int i = array.length - 1; i > 0; i--) { int index = rnd.nextInt(i + 1); // 要素入れ替え(swap) int tmp = array[index]; array[index] = array[i]; array[i] = tmp; } }
上記は、Fisher–Yates shuffle(フィッシャー - イェーツのシャッフル)というアルゴリズムでシャッフルしています。
実行のためのサンプルコードは以下の通りです。
import java.util.Arrays; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; public class FisherYatesShuffleSample { public static void main(String[] args) { int[] targetArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; // シャッフルする前 printArray(targetArray, "No Shuffle"); // シャッフル1回目 shuffle(targetArray); printArray(targetArray, "Shuffle 1 "); // シャッフル2回目 shuffle(targetArray); printArray(targetArray, "Shuffle 2 "); // シャッフル3回目 shuffle(targetArray); printArray(targetArray, "Shuffle 3 "); } public static void shuffle(int[] array) { // 配列が空か1要素ならシャッフルしようがないのので、そのままreturn if (array.length <= 1) { return; } // Fisher–Yates shuffle Random rnd = ThreadLocalRandom.current(); for (int i = array.length - 1; i > 0; i--) { int index = rnd.nextInt(i + 1); // 要素入れ替え(swap) int tmp = array[index]; array[index] = array[i]; array[i] = tmp; } } private static void printArray(int[] array, String headerComment) { System.out.printf("%s -> %s\n\n", headerComment, Arrays.toString(array)); } }
実行結果
No Shuffle -> [1, 2, 3, 4, 5, 6, 7, 8, 9] Shuffle 1 -> [2, 3, 8, 4, 9, 5, 6, 1, 7] Shuffle 2 -> [9, 7, 5, 2, 6, 3, 4, 1, 8] Shuffle 3 -> [2, 8, 5, 4, 1, 6, 7, 3, 9]
まとめ
Fisher–Yates shuffle
で配列をシャッフルすることができるようになりました。