LoginSignup
3
1

More than 3 years have passed since last update.

[小ネタ] Stream を Iterable に変換する

Last updated at Posted at 2017-02-26

やりかた

例として 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 を使用するクラスに渡すと、実装によっては実行時例外が発生する可能性があることを考慮しておいて下さい。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1