常にtrueを返す組み込みのJava 8述語?


回答:


161

Java 8には常にtrueとalways-falseの述語が組み込まれていません。これらを記述する最も簡潔な方法は、

x -> true

そして

x -> false

これらを比較する

Predicates.alwaysTrue() // Guava

そして最後に匿名の内部クラスに:

new Predicate<Object>() {
    public boolean test(Object x) {
        return true;
    }
}

おそらく、Guavaにこれらの組み込み述語があるのは、匿名の内部クラスよりも静的メソッド呼び出しの方が構文上の大きな利点があるためです。Java 8では、ラムダ構文が簡潔であるため、静的メソッド呼び出しを書き出すことには構文上の欠点があります。

ただし、これは構文の比較にすぎません。x -> true複数のクラスにまたがるオカレンスと比較して、それぞれが独自の述語インスタンスを作成する場合と比較して、単一のグローバルtrue述語が存在する場合は、スペースの点で小さな利点があります。これはあなたが心配していることですか?節約は魅力的であるように思われなかった、それはおそらく彼らがそもそも追加されなかった理由です。ただし、将来のリリースで再検討される可能性があります。

2015年4月24日更新

私たちは、静的の様々な追加などという名前の関数と考えられてきたPredicate.alwaysTrueRunnable.noopなど、私たちは、Java SEの将来のバージョンでは、それ以上追加しないことを決定しました。

確かに、名前の付いたものと書き出されたラムダの間に何らかの値がありますが、この値は非常に小さいものです。私たちは、人々が読み書きする方法を学ぶことを期待x -> trueして() -> { }、その使用量は慣用的になること。Function.identity()over の価値さえx -> x疑わしいです。

書き出されたラムダを評価する代わりに既存の関数を再利用することには小さなパフォーマンス上の利点がありますが、これらの種類の関数の使用は非常に少ないため、そのような利点は無視できるほど大きく、APIの膨張には値しません。

Holgerはまた、コメントなどでPredicate.or、などの合成関数を最適化する可能性についても言及しました。これも(JDK-8067971)と見なされていましたが、やや壊れやすくエラーが発生しやすく、実装の労力に見合うほどの頻度で発生しないと考えられていました。

このLambda FAQエントリも参照してください。


14
2つの懸念:最初は簡潔さです。場合は(foo)->{return true;}、私ができる最善のですが、私は良くしたいです。しかし、あなたは育ちましたx->true。これははるかに優れており、最初の問題を軽減します。2番目の問題は、ロジックと静的宣言です。私が使用している場合はx->true、ロジック関与は私が不注意(例えば台無しに可能性が、依然として存在していますx->!true)。しかし、Predicate.alwaysTrue()では、類似したメソッドが1つまたは2つしかないため、論理エラーの余地はありません。さらに、無料でIDEコード補完を取得します。x->trueほぼ問題ありませんが、Predicate.alwaysTrue()上記の理由により、メソッドを作成しました。
Garret Wilson、

10
@GarretWilsonしかし、Predicate.alwaysTrue()誤って書くことで失敗することもありますPredicate.alwaysFalse()
David Conrad

5
もちろん、@ DavidConrad。間違いを犯す方法は常にあり、実際、私は常に新しいものを発明しています。;)私は些細なものの上に、ここで議論を開始したくないが、私はちょうど私のポイントは、静的メソッドを参照して、私は唯一の2つの選択肢が制約された語彙を持っていることであると言うでしょう:alwaysTrue()alwaysFalse()。実際のラムダには、さまざまなバリエーションがあります。基本的には毎回式を再構築しています。本質的にalwaysTrue()は、私がやりたいことの意味ラベルです。x->true実際に毎回それをやり直しています。巨大ではありませんが、考慮事項です。
Garret Wilson

25
標準的なの一つの大きな利点Predicate.alwaysTrue()Predicate.alwaysFalse()インスタンスは、彼らのような方法を組み合わせることにより認識することができること、であるPredicate.orPredicate.andPredicate.negate()。これにより、オーバーヘッドなしでvia を組み合わせて、Predicate変数を事前に初期化しalwaysTrue()、述語を追加andできます。ラムダ式にはオブジェクトIDの保証がないため、これはで失敗する可能性がありx->trueます。ちなみに、メソッドを持つクラスXがあるstatic場合y(){return true;}、使用X::yはさらに短くなりますx->trueが、実際にはお勧めできません…
Holger

10
イディオムに x -> trueは、使用せずに変数を使用しなければならないという欠点があります。これにより、不要な脳の負荷が発生し、IDEで警告も発生します。を使用しようとしましたが_ -> true、これは構文エラーです。Javaには、「未使用のパラメーター」のキーワード(読み取り:キーレター)が欠けています。このようなものがJava 9(または少なくとも:私が死ぬ前のJavaなら何でも^^)になること
kap

4

グアバなし

Boolean.TRUE::booleanValue

3
それは面白い。リクエストの精神を完全に捉えているかどうかはわかりませんが、創造性を発揮するポイントを獲得します!
Garret Wilson

21
しかしPredicate、それは引数を取らないので、ではありません。
Florent Guillaume

1
これは述語ではなく、メソッド参照ですが、簡潔であり、未使用のパラメータについて言及する必要がないというメリットがあります。+1ちなみに、モジュール性の深刻な問題があるグアバの使用を避けているため、私の
賛成に値し

16
メソッド参照は、Supplier <Boolean>には割り当て可能ですが、Predicate <T>には割り当てられません
Daniel K.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.