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

时间:2015-07-24 10:09:30

标签: java algorithm java-stream

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

我已经实现了一种算法,该算法使用类似MapReduce的模式选择一种算法,但对于非常小的流,将项目收集到List中并返回一个随机索引可能更有效。但是,我必须计算它们。 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支持类似函数式编程的接口,缺少元组确实会变得有点痛苦。)

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

我相信原来的问题已经得到了回答,但是我在搜索“ java流至少n个元素”或类似内容时一直在这里着陆,所以也许这对某些人还是有帮助的。

帮助我的是limit()方法。我们将其设置为预期的最小值,然后计算所有元素。一旦达到限制,它将停止计数。这是一个完整的示例:

class Scratch
{
    public static void main(String[] args)
    {
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        List<Integer> list2 = Arrays.asList(1, 2, 3, 4);

        System.out.println(streamContainsAtLeastNElements(list1.stream(), 4));
        // --> false
        System.out.println(streamContainsAtLeastNElements(list2.stream(), 4));
        // --> true
    }

    public static boolean streamContainsAtLeastNElements(Stream<?> stream, long minCount)
    {
        return stream.limit(minCount).count() == minCount;
    }
}

请注意,虽然它将消耗您的流。另外,如果您的流实现一些复杂的排序例程,它可能仍然很慢。在这种情况下,请考虑添加unordered()

答案 2 :(得分:0)

我建议尝试从流的数据源获取此信息。您从哪里获取流的数据?如果源(例如某些集合)可以为您提供您设置的元素数量。如果有一些生产者功能检查它的作用以及是否可以预先估算尺寸。

我输入&#34; stream&#34;我通常会开始考虑一个&#34;配方&#34;我想用这些数据做什么,而不是实际的数据。我认为这与流的设计方式非常接近(这说明了为什么他们不提供计算元素的方法)。

最好的问候,Dido