java - 使用 IntStream 创建数组的随机子集的快速方法

标签 java arrays lambda

我想知道是否可以使用 IntStream 和 lambda 以某种方式快速(一行)创建一个包含现有元素数组的随机子集的数组。

例如,假设我有一群玩家:

Player[] allPlayers;

我想得到这些玩家的随机子集,给定所需子集的维度。传统上我会做类似的事情:

List<Player> players = new ArrayList<Player>(Arrays.asList(allPlayers));

int subsetSize = 8;
Player[] subset = new Player[subsetSize];
for (int i = 0; i < subsetSize; i++) {
  int randIndex = new Random().nextInt(players.size());
  subset[i] = players[randIndex];

  players.remove(randIndex);
}

return subset;

但是这个过程可以用 Java 8 的特性来完成吗?我认为这会使它更加浓缩,这就是我想要实现的目标。我仍然掌握着这些新的 Java 8 特性,例如 IntStream 和 lambdas,但我不知道如何在这种特殊情况下使用它们。

最佳答案

在这种情况下,您希望从输入数组中选择 streamSize 个不同的元素。

您可以使用 Random#ints(randomNumberOrigin, randomNumberBound)方法:

Returns an effectively unlimited stream of pseudorandom int values, each conforming to the given origin (inclusive) and bound (exclusive).

这将返回指定范围内的随机整数流。为确保不同的值,distinct()被称为 limit(...)允许只保留我们想要的元素数量。

Random random = new Random();
Player[] subset = random.ints(0, allPlayers.length)
                        .distinct()
                        .limit(subsetSize)
                        .mapToObj(i -> allPlayers[i])
                        .toArray(Player[]::new);

但是我要指出,即使这是单行代码,它的效率也不如 JB Nizet's solution因为这会继续生成整数,直到找到一个不同的整数。

关于java - 使用 IntStream 创建数组的随机子集的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36357052/

相关文章:

Java以降序显示我的文本文件中的单词?

java - Logback AsyncAppender无法打印方法名称和行号

java - 如何用 GlazedList 中的字符串替换 JTextField 作为过滤器?

javascript - 始终将选定的数据保留在新数组中(React Native)

c - 从文件填充二维数组

php - 如何按日期对这个数组进行排序?

java - 使用 lambda 表达式 java 从比较器返回值

java - Hibernate - Envers 将错误数据写入 AUD 列

c++ - 错误 "lambda is not derived from ' std::function'

lambda - 为什么在函数位置禁止函数对象(但允许 lambda 形式)?