我想知道是否可以使用 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/