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
() -> 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
.