Javaでコレクションをシャッフルする
1. 概要
この簡単な記事では、Javaでコレクションをシャッフルする方法を説明します。 Javaには、 List オブジェクトをシャッフルするための組み込みメソッドがあります。これは、他のコレクションにも使用されます。
2. リストのシャッフル
メソッドjava.util.Collections.shuffle を使用します。このメソッドは、が List を入力として受け取り、インプレースでシャッフルします。 インプレースとは、シャッフルされた要素を使用して新しいリストを作成するのではなく、入力で渡されたものと同じリストをシャッフルすることを意味します。
リストをシャッフルする方法を示す簡単な例を見てみましょう。
List<String> students = Arrays.asList("Foo", "Bar", "Baz", "Qux");
Collections.shuffle(students);
java.util.Collections.shuffleの2番目のバージョンがありますこれはランダム性のカスタムソースも入力として受け入れます。これは、アプリケーションにそのような要件がある場合に、シャッフルを決定論的なプロセスにするために使用できます。
この2番目のバリアントを使用して、2つのリストで同じシャッフルを実現しましょう。
List<String> students_1 = Arrays.asList("Foo", "Bar", "Baz", "Qux");
List<String> students_2 = Arrays.asList("Foo", "Bar", "Baz", "Qux");
int seedValue = 10;
Collections.shuffle(students_1, new Random(seedValue));
Collections.shuffle(students_2, new Random(seedValue));
assertThat(students_1).isEqualTo(students_2);
同じランダム性のソース(同じシード値から初期化)を使用する場合、生成されるランダムな数列は両方のシャッフルで同じになります。したがって、シャッフル後、両方のリストにまったく同じ順序で要素が含まれます。
3. 順序付けられていないコレクションの要素をシャッフルする
たとえば、Set、Map、Queueなどの他のコレクションもシャッフルしたい場合がありますが、これらのコレクションはすべて順序付けされていません —特定の順序を維持していません。
LinkedHashMapやSetとComparatorなどの一部の実装は、固定された順序を維持するため、それらをシャッフルすることもできません。
ただし、最初にリストに変換してから、このリストをシャッフルすることで、要素にランダムにアクセスできます。
Mapの要素をシャッフルする簡単な例を見てみましょう。
Map<Integer, String> studentsById = new HashMap<>();
studentsById.put(1, "Foo");
studentsById.put(2, "Bar");
studentsById.put(3, "Baz");
studentsById.put(4, "Qux");
List<Map.Entry<Integer, String>> shuffledStudentEntries
= new ArrayList<>(studentsById.entrySet());
Collections.shuffle(shuffledStudentEntries);
List<String> shuffledStudents = shuffledStudentEntries.stream()
.map(Map.Entry::getValue)
.collect(Collectors.toList());
同様に、Setの要素をシャッフルできます。
Set<String> students = new HashSet<>(
Arrays.asList("Foo", "Bar", "Baz", "Qux"));
List<String> studentList = new ArrayList<>(students);
Collections.shuffle(studentList);
4. 結論
このクイックチュートリアルでは、使用方法を見ました java.util.Collections.shuffle
これは当然、 List、と直接連携し、間接的に利用して、他のコレクションの要素の順序をランダム化することもできます。 ランダム性のカスタムソースを提供して決定論的にすることで、シャッフルプロセスを制御することもできます。
いつものように、この記事で示されているすべてのコードは、GitHubでから入手できます。