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

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

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

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创建数组的随机子集的快速方法 - 代码日志