LoginSignup
10
8

More than 5 years have passed since last update.

JavaのStreamでHaskellのzipっぽいやつ

Last updated at Posted at 2015-09-12

なんで無いんでしょう? 無いので作りましたというお話です。

zipとは?

ファイル圧縮形式の話ではありません。
2つのリストから、それらの要素をペアにしたリストを返す関数です。

  • リスト1 : [1, 2, 3 ..]
  • リスト2 : ['a', 'b', 'c' ..]
  • 生成されるリスト : [(1, 'a'), (2, 'b'), (3, 'c') ..]

java.util.stream.Stream でこれと同等の機能が提供されているだろうと思い探したのですが、標準ライブラリでは提供されていないようですね。

作成したものと使い方

ZippedStream というクラス1と、付随するクラスを作成しました。
次のように使用します。

利用例
Stream<Integer> stream1 = Stream.of(1, 2, 3);
Stream<String> stream2 = Stream.of("a", "b", "c");

Stream<Pair<Integer, String>> zipped = ZippedStream.of(stream1, stream2);

zipped.forEach(System.out::println);
出力例
(1, a)
(2, b)
(3, c)

ソースストリームが無限ストリームの場合は、生成されるストリームも無限ストリームになります。
ソースストリームに対して遅延バインディングでバインドしますので、(ソースストリームも遅延バインディングであれば、)終端操作の開始前までに大元のソースデータに対して行った変更は、ストリームの要素に反映されます。

また、生成されるストリームの Spliterator の各種特性2は、ソースストリームの Spliterator の特性を反映したものになります。(ここを作りこむのが一番面倒でした!)

比較的ちゃんと作ったつもりですので、よろしければご利用ください。
⇒ jar ファイル

疑問

しかしなぜ、zip の機能が標準 API で提供されていないのでしょうか?
java.util.stream 周りの思想と相いれないやってはいけない何かがあるのでしょうか?!
どなたかアイディアお持ちの方がいれば、コメントいただけると有難いです。

<2015/9/19追記>
zip、java8 のプレビュー版では入っていたものの、正式リリース版で外されたようですね...
自分で色々とテストする中で、少しだけ難しさを理解してきました。Concurrent まわりとか、Spliterator まわりとか、プリミティブ型要素のストリームはどうするんだとか...
色々と難しいっすね。



  1. そこは「StreamUtil#zip」やろ!という話もありますが、諸事情と nmby の好みにより「ZippedStream#of」という名前にした次第です。 

  2. ORDERED, DISTINCT, SORTED, SIZED, NONNULL, IMMUTABLE, CONCURRENT, SUBSIZED の各特性。詳細は Spliterator の API ドキュメント を参照してください。 

10
8
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
10
8