相关疑难解决方法(0)

使用Streams API对Collection中的n个随机不同元素执行操作

我正在尝试使用Java 8中的Streams API从集合中检索n个唯一的随机元素以进行进一步处理,但是没有太多或任何运气.

更准确地说,我想要这样的东西:

Set<Integer> subList = new HashSet<>();
Queue<Integer> collection = new PriorityQueue<>();
collection.addAll(Arrays.asList(1,2,3,4,5,6,7,8,9));
Random random = new Random();
int n = 4;
while (subList.size() < n) {
  subList.add(collection.get(random.nextInt()));
}
sublist.forEach(v -> v.doSomethingFancy());
Run Code Online (Sandbox Code Playgroud)

我想尽可能高效地做到这一点.

可以这样做吗?

编辑:我的第二次尝试 - 虽然不是我的目标:

List<Integer> sublist = new ArrayList<>(collection);
Collections.shuffle(sublist);
sublist.stream().limit(n).forEach(v -> v.doSomethingFancy());
Run Code Online (Sandbox Code Playgroud)

编辑:第三次尝试(灵感来自Holger),如果coll.size()很大且n很小,这将消除大量的shuffle开销:

int n = // unique element count
List<Integer> sublist = new ArrayList<>(collection);   
Random r = new Random();
for(int i = 0; i < n; i++)
    Collections.swap(sublist, i, i + …
Run Code Online (Sandbox Code Playgroud)

java collections java-8

12
推荐指数
1
解决办法
2547
查看次数

是否有一种更优雅的方法来使用java 8从列表中获取随机未使用的项目?

要重构的功能......

<T> T notUsedRandomItem(List<T> allItems, List<T> usedItems) {
    return allItems.stream()
            .filter(item -> !usedItems.contains(item))
            .sorted((o1, o2) -> new Random().nextInt(2) - 1)
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Did not find item!"));
}
Run Code Online (Sandbox Code Playgroud)

功能可能会像这样使用......

System.out.println(
            notUsedRandomItem(
                    Arrays.asList(1, 2, 3, 4), 
                    Arrays.asList(1, 2)
            )
    ); // Should print either 3 or 4
Run Code Online (Sandbox Code Playgroud)

编辑:通过针对人员列表运行它们来收集建议的实现和测试效率.

edit2:为Person类添加了缺少的equals方法.

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static java.util.stream.Collectors.toList;

class Functions {

    <T> T notUsedRandomItemOriginal(List<T> allItems, List<T> usedItems) {
        return allItems.stream()
                .filter(item -> !usedItems.contains(item))
                .sorted((o1, o2) -> …
Run Code Online (Sandbox Code Playgroud)

java java-stream

8
推荐指数
1
解决办法
165
查看次数

标签 统计

java ×2

collections ×1

java-8 ×1

java-stream ×1