collection.stream()。skip()。findFirst()的效率

时间:2016-04-14 02:52:40

标签: java collections java-8 java-stream

假设setHashSetn个元素,而kint(包括)和{{1}之间的0n (独家)。

有人可以用简单的方式解释当你这样做时实际发生了什么吗?

set.stream().skip(k).findFirst();

特别是,这个时间复杂度是多少?将spliterator()添加到Collection界面是否意味着我们现在可以更快地访问"随机"收集的元素比Java 7可能的更多?

2 个答案:

答案 0 :(得分:6)

当前实现具有O(k)复杂性,并且与以下内容无关:

Iterator<?> it = set.iterator();
for(int i=0; i<k && it.hasNext(); i++) it.next();
return it.hasNext() ? Optional.of(it.next()) : Optional.empty();

当前实现从不考虑顺序流的ORDERED特性。 @ the8472中引用的代码段仅适用于并行流。在并行情况下,摊销的复杂性大致为O(k / n),其中n是处理器的数量。

答案 1 :(得分:3)

正如louis提到的那样,跳过对无序流没有意义,实际上它是以(以下方法)实现的,其中以下方法在某些情况下优化了跳过:

        Spliterator<T> unorderedSkipLimitSpliterator(Spliterator<T> s,
                                                     long skip, long limit, long sizeIfKnown) {
            if (skip <= sizeIfKnown) {
                // Use just the limit if the number of elements
                // to skip is <= the known pipeline size
                limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
                skip = 0;
            }
            return new StreamSpliterators.UnorderedSliceSpliterator.OfRef<>(s, skip, limit);
        }

这是有效的,因为它等同于以不同的顺序遍历源集合。