Explain how this lambda can be assigned to an Iterable

前端 未结 2 1746
离开以前
离开以前 2021-01-04 10:21

I came across some clever code to convert an Iterator to a Stream from Karol on this post. I have to admit that I don\'t completely understand how the lambda is allowed to b

2条回答
  •  鱼传尺愫
    2021-01-04 11:01

    () -> iterator is not “acting as a Supplier function”. Lambda expressions can be assigned to any congruent functional interface type. And there is no requirement for a functional interface to be annotated with @FunctionalInterface. You can create an Iterable with a lambda expression, which will implement the Iterable.iterator() method, which is the only abstract method of that interface. However, implementing it by returning the same Iterator instance each time may violate the expectation of being able to iterate this object multiple times (which is the reason why Stream doesn’t implement Iterable despite having an iterator() method).

    This solution will work in this narrow context, but isn’t clever.

    The sequence

    final Iterable iterable = () -> iterator; … iterable.spliterator()
    

    just introduces an additional step before Spliterators.spliteratorUnknownSize(iterator, 0), which is how the default method of Iterable.spliterator() is implemented.

    So

    static  Stream iteratorToFiniteStream(final Iterator iterator) {
        final Iterable iterable = () -> iterator;
        return StreamSupport.stream(iterable.spliterator(), false);
    }
    

    is just a less efficient variant of

    static  Stream iteratorToFiniteStream(final Iterator iterator) {
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
    }
    

    If you compare this to the accepted answer of the Q&A you’ve linked, you’ll see that it is exactly that, but that answer takes the opportunity of passing specific characteristics instead of 0.

提交回复
热议问题