Fundamentals

Default Methods

Collections

Idioms and Techniques

Design Rationale

Advanced Questions

How can I turn a Stream into an Iterable?

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) {
    ...
}