Stream#reject が欲しいと切に願う
まあ実際は切に願うほどではないんですけど、
List.of("a", "", "b").stream()
.reject(s -> s.isEmpty())
.collect(Collectors.toList());
// => ["a", "b"]
みたいに書きたいわけです。
でも実際はそんなものは無いわけで...
Stream#filter
を使って書くわけです。
いろいろと書いてみると...
実装する関数で否定を返す
List.of("a", "", "b").stream()
.filter(s -> !s.isEmpty())
.collect(Collectors.toList());
まあシンプルな実装なら悪くないんですけど、複雑な条件とかだと頭混乱しちゃいます。
あとシンプルな条件でも、ぱっと見で !
を見逃すケースが怖いですよね。
Predicate#negate を使う
List.of("a", "", "b").stream()
.filter(((Predicate<String>) (s -> s.isEmpty())).negate())
.collect(Collectors.toList());
// う~んんんキャストうざい!
Predicate<String> emptyText = s -> s.isEmpty();
List.of("a", "", "b").stream()
.filter(emptyText.negate())
.collect(Collectors.toList());
Predicate#negate
自体はすごくやりたいことを実現できているんですが、キャストがががが...
否定条件を返すメソッド作る
// 元の条件の否定条件の Predicate 返す
private <E> Predicate<? super E> not(Predicate<? super E> p) {
return p.negate();
}
こういうの作って、
List.of("a", "", "b").stream()
.filter(not(s -> s.isEmpty()))
.collect(Collectors.toList());
うん!悪くない!
ただ、not
をユーティリティーとかにしてしまうと、StreamUtils.not
みたいになって記述が長くなってしまうのがオシイ感じです。
ラップしてしまえ!
public class StreamWrapper<T> {
private final Stream<T> stream;
// private constructor
private StreamWrapper(Stream<T> src) {
this.stream = src;
}
// make instance
public static <T> StreamWrapper<T> of(Stream<T> src) {
return new StreamWrapper(src);
}
// Stream#filter をラップ
public StreamWrapper<T> filter(Predicate<T> p) {
return this.of(stream.filter(p));
}
// Stream#collect をラップ
public <R, A> R collect(Collector<T, A, R> c) {
return stream.collect(c);
}
// ...他にもいっぱいラップ
/**
* このストリームの要素のうち、指定された述語に一致<b>しない</b>ものから構成されるストリームを返します。
* <p>
* これは中間操作です。
*
* @param predicate
* 各要素を含めるべきか判定する目的で各要素に適用する、非干渉でステートレスな述語
* @return 新しいストリーム
*/
public StreamWrapper<T> reject(Predicate<T> predicate) {
return this.of(stream.filter(predicate.negate()));
}
}
こういうの作って、
StreamWrapper.of(List.of("a", "", "b").stream())
.reject(s -> s.isEmpty())
.collect(Collectors.toList());
やったね!
(まあ、)reject
ごときのためにこんなに手間のかかることしないけれど...
実装クラス作ってしまえ!
J・M・T(実装・マジ・手間 )
なかなかに手間のかかる子 Stream API
いざ「こういう中間操作欲しい!」ってなってもなかなか拡張するのには骨が折れます。
Java9 で takeWhile
dropWhile
ofNullable
とか追加されて便利になっていますが、zip
など主要っぽい機能は実装されていない(reject
も)ので必要に応じて拡張してみてはいかがでしょう?
Author And Source
この問題について(Stream#reject が欲しいと切に願う), 我々は、より多くの情報をここで見つけました https://qiita.com/kurararara/items/775a84325c3fe15a779a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .