java - Collections.shuffle() 真的足够随机吗?实际例子似乎否定了这种说法

标签 java arrays collections random shuffle

我在 java.util.List 中有 1000 个唯一的对象,每个对象都引用一个图像,1000 个列表中的每个图像都是唯一的,现在我想打乱它们,以便我可以使用前 20 个对象并将它们呈现给网站用户。 然后,用户可以单击一个显示“随机播放”的按钮,我再次从头开始检索 1000 张图像并再次调用 shuffle()。 然而,似乎在 1000 个图像对象中,我经常在 20 个图像选择之间一次又一次地看到相同的图像。

好像哪里不对,有什么更好的建议,建议吗?

我的代码很简单:

List<String> imagePaths = get1000Images();
Collections.shuffle(imagePaths);

int i = 0;
for (String path: imagePaths) {
  ... do something with the path ...
  i++;
  if (i >= 20) break;
}

我知道 Collections.shuffle() 分布良好: 参见例如 http://blog.ryanrampersad.com/2012/03/03/more-on-shuffling-an-array-correctly/

不过,我只是感觉,在1000张中的20张图片中,一遍又一遍地看到同一张图片的概率应该小得多......

高度赞赏输入。

最佳答案

看到不存在的模式是人类的天性。许多人将行星和恒星的模式视为指导他们的生活。

在 PI 的前 1000 位数字中,连续有六个 9。这是否意味着 PI 的数字不是随机的?不。该模式不会像您预期的那样再次出现。

话虽如此,Random 并不是完全随机的,它会在 2^48 次调用后重复。 (它使用 48 位种子)这意味着它不可能生成所有可能的 longdouble 使用它。如果您想要更多的随机性,您可以改用 SecureRandom with shuffle。

听起来你想要的是这样的

List<String> imagePaths = new ArrayList<>();

// called repeatedly
if (imagePaths.size() <= 500) {
    imagePaths = get1000Images();
    Collections.shuffle(imagePaths);
}

for (String path: imagePaths.subList(0, 20)) {
  ... do something with the path ...
}

imagePaths = imagePaths.subList(20, imagePaths.size());

这将确保您不会在最近 500 次调用中看到相同的图像。

关于java - Collections.shuffle() 真的足够随机吗?实际例子似乎否定了这种说法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9701639/

相关文章:

c# - 是否有任何 C++11 emplace/emplace_back 函数的 C# 模拟?

c# - 如何查看每秒更新的图表中的最后 10 个数据点?

java - map 和列表中的 ModCount

java - 通过匿名内部类创建线程

java - Elasticsearch无节点可用异常

arrays - 子集和问题【嵌套循环解法?】

java - 什么数组/集合对象对于 "contains"函数最有效?

java - DateTimeFormatter 抛出日期字符串的 DateTimeParseException

javascript - 在浏览器中打开文件而不是下载(包括 .doc、.xls 等文件)

c++ - Getline忽略输入的第一个字符