我有一种方法,在某些时候洗牌List.重要的是我以后可以重现这个改组.为了实现这一点,我传递Random给后来传递给的方法Collection.shuffle(List, Random).我期望使用相同的Random和相同的列表将导致相同的混洗列表,但显然我遗漏了一些东西.
使用Strings代替我的对象的示例代码:
@Test
public final void shuffleTest() {
Random random = new Random(555);
List<String> text = new ArrayList<>();
text.add("one");
text.add("two");
text.add("three");
text.add("four");
List<String> shuffled = shuffleList(new ArrayList<>(text), random);
List<String> shuffled2 = shuffleList(new ArrayList<>(text), random);
Assertions.assertThat(shuffled).isEqualTo(shuffled2);
}
private List<String> shuffleList(List<String> text, Random random) {
Collections.shuffle(text, random);
return text;
}
Run Code Online (Sandbox Code Playgroud)
我确实注意到,如果不是通过它Random,我会传递种子,并且new Random(seed)每次它确实有效,但我想避免这种情况.
您自己提供了答案。初始化一个Random实例后,它会产生一个伪随机数序列。这个序列中的一些将被第一次 shuffle 消耗,因此第二次 shuffle 将使用序列的下一位。为了使用相同的序列,Random实例在每次洗牌之前必须处于相同的状态。具有相同种子的新实例符合要求。
如果你这样做:
List<String> shuffled = shuffleList(new ArrayList<>(text), new Random(555));
List<String> shuffled2 = shuffleList(new ArrayList<>(text), new Random(555));
Run Code Online (Sandbox Code Playgroud)
他们确实是平等的.
但是,您使用相同的随机实例两次:在第一次shuffle之后,Random它处于与之前不同的状态,因此它将以不同方式对列表进行洗牌.
| 归档时间: |
|
| 查看次数: |
547 次 |
| 最近记录: |