1. Overview
1.概述
In this quick article, we’ll see how we can shuffle a collection in Java. Java has a built-in method for shuffling List objects — we’ll utilize it for other collections as well.
在这篇文章中,我们将看到如何在Java中洗牌一个集合。Java有一个内置的方法来洗刷List对象–我们也将利用它来洗刷其他集合。
2. Shuffling a List
2.洗牌
We’ll use the method java.util.Collections.shuffle, which takes as input a List and shuffles it in-place. By in-place, we mean that it shuffles the same list as passed in input instead of creating a new one with shuffled elements.
我们将使用java.util.Collections.shuffle,该方法将接收一个List作为输入,并将其就地洗牌。所谓原地洗牌,我们的意思是,它洗的是输入的同一个列表,而不是用洗过的元素创建一个新的列表。
Let’s look at a quick example showing how to shuffle a List:
让我们看一个快速的例子,展示如何洗牌List。
List<String> students = Arrays.asList("Foo", "Bar", "Baz", "Qux");
Collections.shuffle(students);
There’s a second version of java.util.Collections.shuffle that also accepts as input a custom source of randomness. This can be used to make shuffling a deterministic process if we have such a requirement for our application.
java.util.Collections.shuffle它也接受随机性的自定义源作为输入。如果我们的应用有这样的要求,这可以用来使洗牌成为一个确定性的过程。
Let’s use this second variant to achieve the same shuffling on two lists:
让我们使用第二种变体来实现两个列表上的相同洗牌:。
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);
When using identical sources of randomness (initialized from same seed value), the generated random number sequence will be the same for both shuffles. Thus, after shuffling, both lists will contain elements in the exact same order.
当使用相同的随机性来源(从相同的种子值初始化)时,两次洗牌产生的随机数序列将是相同的。因此,洗牌后,两个列表将包含顺序完全相同的元素。
3. Shuffling Elements of Unordered Collections
3.无序集合的元素洗牌
We may want to shuffle other collections as well such as Set, Map, or Queue, for example, but all these collections are unordered — they don’t maintain any specific order.
我们可能也想对其他集合进行洗牌,例如Set、Map、或Queue,但是所有这些集合都是无序的–它们不保持任何特定的顺序。
Some implementations, such as LinkedHashMap, or a Set with a Comparator – do maintain a fixed order, thus we cannot shuffle them either.
一些实现,比如LinkedHashMap,或者带有Comparator的Set–确实保持了一个固定的顺序,因此我们也不能对它们进行清洗。
However, we can still access their elements randomly by converting them first into a List, then shuffling this List.
然而,我们仍然可以通过将它们首先转换成List,然后洗刷这个List来随机访问它们的元素。
Let’s see a quick example of shuffling elements of a Map:
让我们看一个洗刷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());
Similarly, we can shuffle elements of a Set:
类似地,我们可以对Set的元素进行洗牌。
Set<String> students = new HashSet<>(
Arrays.asList("Foo", "Bar", "Baz", "Qux"));
List<String> studentList = new ArrayList<>(students);
Collections.shuffle(studentList);
4. Conclusion
4.结论
In this quick tutorial, we saw how to use java.util.Collections.shuffle to shuffle various collections in Java.
在这个快速教程中,我们看到了如何使用java.util.Collections.shuffle来洗刷Java中的各种集合。
This naturally works directly with a List, and we can utilize it indirectly to randomize the order of elements in other collections as well. We can also control the shuffling process by providing a custom source of randomness and make it deterministic.
这自然可以直接用于List,,我们也可以间接地利用它来随机化其他集合中元素的顺序。我们还可以通过提供一个自定义的随机性来源来控制洗牌过程,并使其具有确定性。
As usual, all code demonstrated in this article is available over on GitHub.
像往常一样,本文中演示的所有代码都可以在GitHub上找到。