kennytm described why it's unsafe to treat a Stream
as an Iterable
, and Zhong Yu offered a workaround that permits using a Stream
as in Iterable
, albeit in an unsafe manner. It's possible to get the best of both worlds: a reusable Iterable
from a Stream
that meets all the guarantees made by the Iterable
specification.
Note: SomeType
is not a type parameter here--you need to replace it with a proper type (e.g., String
) or resort to reflection
Stream<SomeType> stream = ...;
Iterable<SomeType> iterable = stream.collect(toList()):
There is one major disadvantage:
The benefits of lazy iteration will be lost. If you planned to immediately iterate over all values in the current thread, any overhead will be negligible. However, if you planned to iterate only partially or in a different thread, this immediate and complete iteration could have unintended consequences.
The big advantage, of course, is that you can reuse the Iterable
, whereas (Iterable<SomeType>) stream::iterator
would only permit a single use. If the receiving code will be iterating over the collection multiple times, this is not only necessary, but likely beneficial to performance.
Stream
to legacy APIs that expectsIterable
– ZhongYugetIterable()
toreturn s::iterator;
– ZhongYufor (T element : stream::iterator)
, so I'd still prefer if Stream would also implementIterable
or a methodtoIterable()
. – Thorsten