私は最近、Java 8で導入されたLambda式を習得しました。関数型インターフェースを使用するときはいつでも、関数型インターフェースを実装するクラスを作成する代わりに、常にLambda式を使用する傾向があります。
これは良い習慣と考えられていますか?または、機能インターフェイスにLambdaを使用することが適切でない状況ですか?
私は最近、Java 8で導入されたLambda式を習得しました。関数型インターフェースを使用するときはいつでも、関数型インターフェースを実装するクラスを作成する代わりに、常にLambda式を使用する傾向があります。
これは良い習慣と考えられていますか?または、機能インターフェイスにLambdaを使用することが適切でない状況ですか?
回答:
ラムダを使用しないことを考慮する必要がある多くの基準があります。
priceIsOver100
。 x -> x.price > 100
その名前と同じくらい明確です。isEligibleVoter
そのような名前は、条件の長いリストを置き換えることを意味します。船外に出ないでください。ソフトウェアは簡単に変更できます。疑問がある場合は、両方の方法で書き、どちらが読みやすいかを確認してください。
カールビーレフェルトの答えを支持しますが、簡単に追加したいと思います。
Karl Bielefeldtが受け入れた回答は正しいです。もう1つ区別を追加できます。
クラス内のメソッド内にネストされたラムダコードは、そのメソッドとクラス内にある効果的に最終的な変数にアクセスできます。
機能的なインターフェースを実装するクラスを作成しても、呼び出しコードの状態に直接アクセスすることはできません。
Javaチュートリアル(エンファシスマイニング)を引用するには:
ローカルクラスおよび匿名クラスと同様に、ラムダ式は変数をキャプチャできます。それらは、囲むスコープのローカル変数への同じアクセス権を持ちます。ただし、ローカルクラスや匿名クラスとは異なり、ラムダ式にはシャドウイングの問題はありません(詳細については、シャドウイングを参照してください)。ラムダ式のスコープはレキシカルです。つまり、スーパータイプから名前を継承せず、新しいレベルのスコープを導入しません。ラムダ式の宣言は、囲んでいる環境の場合と同じように解釈されます。
そのため、長いコードを引き出して命名することには利点がありますが、それを囲むメソッドとクラスの状態への直接アクセスの単純さに対して、それを比較検討する必要があります。
見る:
これは簡単な選択かもしれませんが、他の回答で作成された他のすべての優れた点に、私は追加します:
可能な場合は、メソッド参照を優先します。比較:
employees.stream()
.map(Employee::getName)
.forEach(System.out::println);
対
employees.stream()
.map(employee -> employee.getName())
.forEach(employeeName -> System.out.println(employeeName));
メソッド参照を使用すると、あなたのような怠惰な名前に通常の冗長および/またはリードであるラムダの引数(複数可)、名前を付ける必要が保存されますe
かをx
。