やりかた
例として Files#write(Path, Iterable<? extends CharSequence> lines, OpenOption...)
を使います。
Stream<String> stream = Stream.of("foo", "bar", "baz");
Iterable<String> iterable = stream::iterator;
Files.write(Paths.get("test.txt"), iterable);
あるいは
Stream<CharSequence> stream = Stream.of("foo", "bar", "baz");
Files.write(Paths.get("test.txt"), stream::iterator);
ちなみに
Stream<String> stream = Stream.of("foo", "bar", "baz");
// コンパイルエラー
Files.write(Paths.get("test.txt"), stream::iterator);
// これなら通る
Files.write(Paths.get("test.txt"), (Iterable<String>)stream::iterator);
背景と注意点
Stream/BaseStream は iterator()
というメソッドを持ちますが Iterable を実装していません。Iterable#iterator()
は繰り返し呼ばれる可能性があるというのが理由らしいです。
Iterable#iterator()
のドキュメントにはイテレータを返すということしか書かれていませんが、BaseStream#iterator()
には終端操作である、つまり一度しか呼べない旨が明記されています。
参考: Why is Stream not an Iterable ?
したがって、前掲の方法で変換したものを安易に Iterable を使用するクラスに渡すと、実装によっては実行時例外が発生する可能性があることを考慮しておいて下さい。