繁体   English   中英

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

[英]Can I check if Java 8 stream contains at least n elements

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

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

PS:我知道有时候没有必要优化代码; 但我想尝试一下,只是为了体验。 我是学生。

PPS:我在这里复制了我的算法,万一有人感兴趣(或者想找bug,我还没有测试过;-)

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支持类似函数编程的接口,缺少元组确实会变得有点痛苦)。

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

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

我建议尝试从流的数据源获取此信息。 您从哪里获取流的数据? 如果源(例如某些集合)可以为您提供所设置的元素数。 如果它是一些生产者功能检查它做了什么以及是否可以预先估计大小。

在我键入“stream”的那一刻,我通常会开始考虑我想要对这些数据做什么的“配方”,而不是实际的数据。 我认为这与流的设计方式很接近(这说明了为什么它们没有提供计算元素的方法)。

最好的问候,Dido

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM