Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiency of collection.stream().skip().findFirst()

Suppose set is a HashSet with n elements and k is some int between 0 (inclusive) and n (exclusive).

Can somebody explain, in simple terms, what actually happens when you do this?

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

In particular, what is the time complexity of this? Does the addition of spliterator() to the Collection interface mean that we now have faster access to "random" elements of collections than would have been possible with Java 7?

like image 930
Paul Boddington Avatar asked Apr 14 '16 02:04

Paul Boddington


People also ask

What is the use of findfirst in stream?

Stream findFirst() returns an Optional (a container object which may or may not contain a non-null value) describing the first element of this stream, or an empty Optional if the stream is empty. If the stream has no encounter order, then any element may be returned.

What is stream skip in Java?

Java Stream skip is one of it’s operations, which we will explore in this article. Stream.skip (n) method is to truncate, by ignoring first n elements and return new Stream containing rest of the elements.

What is the use of findany () method in stream?

Note : findAny () is a terminal-short-circuiting operation of Stream interface. This method returns first element satisfying the intermediate operations. Example 1 : findFirst () function on Stream of Integers.

How to create a null-safe collection from a stream in Java?

Using Optional can be arguably considered as the best overall strategy to create a null-safe collection from a stream. Let's see how we can use it followed by a quick discussion below: Optional.ofNullable (collection) creates an Optional object from the passed-in collection. An empty Optional object is created if the collection is null.


2 Answers

Current implementation has O(k) complexity and moreless equivalent to the following:

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

Current implementation never takes into account ORDERED characteristic for sequential streams. The piece of code cited in @the8472 answer works for parallel streams only. In parallel case the amortized complexity is roughly O(k/n) where n is the number of processors.

like image 54
Tagir Valeev Avatar answered Sep 20 '22 06:09

Tagir Valeev


As louis mentions skip does not really make sense on unordered streams, in fact it's currently (jdk 1.8) implemented in a way where the following method optimizes the skip away under some circumstances:

        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);
        }

This is valid because it is equivalent to simply traversing the source collection in a different order.

like image 40
the8472 Avatar answered Sep 20 '22 06:09

the8472