java - 我可以检查 Java 8 流是否至少包含 n 个元素

标签 java algorithm java-stream

我有一个 Java 8 流,我想从中(一致地)随机选择一个元素。流可以包含从零到数万个元素的任何位置。

我已经实现了一种算法,该算法使用类似 MapReduce 的模式选择一个,但对于非常小的流,将项目收集到列表中并返回一个具有随机索引的项目可能会更有效。然而,为此我必须计算它们。 Streams 确实有一个 count() 方法,但它会计算所有这些,我对实际计数并不感兴趣,我只关心它是否包含超过待确定的数字。有谁知道这种方法是否存在?我找不到它,但可能有一些我忽略的东西或一些聪明的技巧无论如何都能找到它。

P.S.:我知道有时候优化代码是不必要的;但我还是想尝试一下,只是为了体验一下。我是学生。

P.P.S.:我在这里复制了我的算法,以防有人感兴趣(或者想寻找错误,我还没有测试过 ;-)

stream
    .parallel()
    .map(t -> new Pair<T, Integer>(t, 1))
    .reduce((Pair<T, Integer> t, Pair<T, Integer> u) -> {
        if (rand.nextDouble() <= (t.getValue1() / (double) (t.getValue1() + u.getValue1()))) {
            return new Pair<>(t.getValue0(), t.getValue1() + u.getValue1());
        } else {
            return new Pair<>(u.getValue0(), t.getValue1() + u.getValue1());
        }
    })
    .map(t -> t.getValue0());

(这些对来自 org.javatuples,现在 Java 支持类似函数式编程的接口(interface),缺少元组确实变得有点痛苦)。

最佳答案

您的代码不会从均匀分布中返回元素。这取决于顺序,流提供元素以减少方法。在一般情况下,您不能认为该订单不是特殊订单。解决您的任务:如果您有足够的内存,则可以编写 RandomComparator(将以前的结果保存在 Map 中),使用此比较器对您的流进行排序并获取第一个元素(不要使用 findAny)。如果流太大,可以使用 RandomFilter 对其进行采样。

顺便说一句,如果您的流中有 SIZED 标志,则任务很简单。只需获取大小,生成随机索引并制作 spip :)

关于java - 我可以检查 Java 8 流是否至少包含 n 个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31607753/

相关文章:

java - 表示给定范围内所有数字的最佳方式是什么? (一些限制)

java - 使用循环以类似Python的方式连接Java中的数组元素

java - 使用自定义主题的 actionbar 时如何更改 actionbarsherlock 菜单项字体?

algorithm - 在不相交间隔的排序列表中插入间隔

Java嵌套Map/List - 按列表内容过滤,返回父对象

java - 可以将其转换为单行流吗?

java - 使用流 API 分组时多个组中的单个元素

java - EJB 池与线程安全和@PreDestroy

java - 具有offer和flush的非阻塞并发队列

image - 罪恶之城效应