Stream
inherits an iterator() method to produce an Iterator
.
But I need an Iterable
rather than an Iterator
.
For example, given this string:
String input = "this\n" +
"that\n" +
"the_other";
…I need to pass those parts of string as an Iterable
to a specific library. Calling input.lines()
yields a Stream
. So I would be set if I could make that Stream
into a Iterable
of its elements.
As explained in Why does Stream<T> not implement Iterable<T>?, an Iterable
bears the expectation to be able to provide an Iterator
more than once, which a Stream
can’t fulfill. So while you can create an Iterable
out of a Stream
for an ad-hoc use, you have to be careful about whether attempts to iterate it multiple times could exist.
Since you said, “I need to pass those parts of string as an Iterable
to a specific library”, there is no general solution as the code using the Iterable
is outside your control.
But if you are the one who creates the stream, it is possible to create a valid Iterable
which will simply repeat the stream construction every time an Iterator
is requested:
Iterable<String> lines = () -> "this\nthat\nthe_other".lines().iterator();
This fulfills the expectation of supporting an arbitrary number of iterations, while not consuming more resources than a single stream when being traversed only once.
for(var s: lines) System.out.println(s);
lines.forEach(System.out::println);
System.out.println(String.join("\n", lines));