我有一种方法可以在某个时候改变List
。重要的是我以后可以重现这个改组。为实现此目的,我将Random
传递给方法,然后传递给Collection.shuffle(List, Random)
。我期望使用相同的Random和相同的列表会产生相同的混洗列表,但显然我错过了一些东西。
使用String
代替我的对象的示例代码:
@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;
}
我确实注意到,如果不是传递Random
,我会传递种子并在每次有效时执行new Random(seed)
,但我想避免这种情况。
答案 0 :(得分:6)
如果你这样做了:
List<String> shuffled = shuffleList(new ArrayList<>(text), new Random(555));
List<String> shuffled2 = shuffleList(new ArrayList<>(text), new Random(555));
他们确实是平等的。
但是,您使用相同的随机实例两次:在第一次随机播放后,Random
处于与之前不同的状态,因此它将以不同方式对列表进行洗牌。
答案 1 :(得分:3)
您自己提供了答案。初始化+ (NSData *) xorData:(NSData *)data1 with:(NSData *)data2
{
// make data1 smaller
if (data1.length > data2.length) {
NSData *t = data1;
data1 = data2;
data2 = t;
}
char *xor = (char *) malloc(data2.length * sizeof(char));
char * data1Bytes = (char *) data1.bytes;
char * data2Bytes = (char *) data2.bytes;
for (int i = 0; i <data1.length; i++)
{
xor[i] = data1Bytes[i] ^ data2Bytes[i];
}
NSMutableData *data = [[[NSMutableData alloc] initWithBytes:xor length:data1.length] autorelease];
[data appendData:[data2 subdataWithRange:NSMakeRange(data1.length, data2.length - data1.length)]];
free(xor);
return [NSData dataWithData:data];
}
实例后,它将生成一系列伪随机数。第一个shuffle将消耗这些序列中的一些,因此第二个shuffle将使用序列的下一个位。为了使用相同的序列,Random
实例必须在每个shuffle之前处于相同的状态。具有相同种子的新实例符合该法案。
答案 2 :(得分:2)
第一次拨打Collections.shuffle(text, random);
将会#34;用完&#34;您传入的Random
实例中的一些随机数。如果第一组随机数与第二组相同,则混洗列表将是相同的,以及您使用的方式{{1只有当Random
的{{1}}个数字重复出现时,才会发生这种情况。
如果您希望使用相同的随机数组对两个列表进行排序,则必须为它们提供具有相同种子的n
,并且使用相同数量的随机数(在这种情况下) ,0)。
e.g:
Random(555)