Stream has an iterator() method which will turn it into an Iterator. But sometimes you want an Iterable, not an Iterator, for example, to use the enhanced-for loop, or to pass to an existing API that requires an Iterable. Given a Stream s, the following results in an Iterable:
s::iterator
This is a bit counterintuitive. The Iterable interface has a single abstract method, so it’s a functional interface. That means that it can be implemented using a lambda expression or a method reference. Even though Stream does not implement Iterable, it has a method iterator() that matches the shape of the abstract method of the Iterable interface. (That is, it takes no arguments, and it returns an Iterator.) So a method reference to the Stream’s iterator() method works to implement the Iterable interface.
If you want to use this directly in an enhanced-for loop, you have to apply a cast in order to establish a target type for the method reference. For example:
Stream<String> stream = ...;
for (String s : (Iterable<String>)stream::iterator) {
...
}

Leave a Reply