Lightweight-Stream-APIとは?
Stream API from Java 8 rewritten on iterators for Java 7 and below.
Java 8から導入されたStreamのようなものをJava 7以前で使うためのLibrary
Streamについては調べればいくらでも資料はあるので詳細は割愛します
StreamだけでなくOptionalも実装されているため、AndroidでStream + Optionalを使いたい場合によいLibraryで私はよく使ってます(Kotlinの場合はそこまで必要としませんが...
Lightweight-Stream-API 特有の中間操作(intermediate operation)
Lightweight-Stream-APIのStreamには、Library特有の便利な中間操作(intermediate operation)が実装されてます
例えば、要素のうちnull以外でfilterする withoutNulls
は便利ですね
Stream.of("a", null, "b") .withoutNulls() .forEach(System.out::println); // 結果: // a // b
このような便利な中間操作はJava 8以降のStreamには実装されていません
Libraryだからこそさくっと便利なものが実装できるのはLightweight-Stream-APIのいいところですね
他にもLightweight-Stream-API 特有の実装はいくつかあるので気になる人は見てみてください!
独自に実装してるとはいえそこまで複雑ではなく、自分でも拡張できそうだなーと思って、今回equalsOnly
という中間操作(intermediate operation)のメソッドを実装してPull Requestを出してみました
equalsOnly
- 要素のうち指定したオブジェクトと同じものだけでfilterする
どんなものを実装したのかはごちゃごちゃ説明するよりコードを見てもらうほうが早いです
流れてくる各要素をメソッドの引数で渡すobjectと同じかどうかをチェックしてfilterしてるだけです
/** * Returns {@code Stream} with elements that is equality of {@code object} only. * <p> * <p>This is an intermediate operation. * * @param object object * @return the new stream */ public Stream<T> equalsOnly(final T object) { return filter(new Predicate<T>() { @Override public boolean test(T value) { return Objects.equals(value, object); } }); }
ね?実装簡単でしょ!
んで、使い方は以下のような感じでマッチしたものだけ後続のStreamに流れる仕組みです
List<String> match = Stream.of("a", "b", "c") .equalsOnly("b") .toList(); // match -> ["b"]
どうしてequalsOnly
がほしかったのか
私がやっているプロジェクトのコードでfilterしてequalsするみたいなコードが度々出現していて「これ書くの面倒なー」と思っていたので、実装も楽だしワンチャン提案してみるかーと思った感じです
例えば雑に説明すると、以下のようにfilter内でequalsだけを条件としてる箇所がざっくり数えるだけでも30ヶ所はあるんですよねー
Stream.of("a", "b", "c") .filter(s -> Objects.equals(s, "b")) .(以降処理は続く...
これをさくっと書きたい! equalsOnly
みたいなの作ればさくっと書けるはず!と思って仕事中に実装して、提案してみた感じです
次のリリースがされたらequalsOnly
使えるようになると思うので、同じようにほしかった!!という人は使ってほしい気持ち!!
Pull Requestわりと雑に出したけど案外あっさりMergeされた
とりあえず提案程度にコード書いてみたぞい!って気持ちをぶつけたかったので雑に[Proposal]って頭につけて、Pull Requestの概要にも実装したequalsOnly
の使い方だけわかるコードを書いてみた
実際のPull Requestは以下です
同僚には「それはさすがにMergeされないのではー?」って言われて、「せやな」って気持ちだったけど、朝起きてみたらMergeされてた
Javadocとテストコードをちゃんと書いておいてよかったなーという気持ち
Libraryとしてテストコード書くっぽい! + 勝手にCI回ってテストしてくれる!というのは、コントリビュートする側としてはなんか安心するので良いなーと思った
実装されたものがいい感じでテストも書いて通ってれば、ごちゃごちゃ英語で説明書かなくても通じる世界はある!みたいなとても楽観的な考えでやっていきだなーと思った次第です
とはいえ私みたいなのが量産されるのは微妙なので、英語はちゃんとできるようになりたいものです...
v1.2.0で実装したequalsOnlyが追加されてました - 2018/06/20 追記
めでたい!
Added Stream.equalsOnly operator (thanks to @operando)
Lightweight-Stream-API もっと便利になってほしい!!
無法地帯にならない程度に便利なメソッドなど増えてほしいぞ!!
私も他に便利そうなの思いついたらまたPull Request出すぞ!!