多くの新しい Java バージョンがリリースされているにもかかわらず、Java 8 は、その強力で革新的な機能により、依然として最も広く採用されているバージョンの 1 つです。 Java 8 で導入されたラムダ式は、関数型プログラミングを可能にして Java をより簡潔かつ効率的にするため、特に人気があります。この機能により、開発者は冗長な匿名内部クラスを合理化された構文に置き換えることができるため、コードがより読みやすく、保守しやすくなります。
このガイドでは、ラムダ式がどのようにコードを簡素化し、コレクション内のデータ処理を強化し、Java 開発者が最新のパフォーマンスの高いアプリケーションを作成できるようにするかを説明します。
本質的に、ラムダ式は、関数型インターフェイスの単一の抽象メソッドをより単純な構文で表現する方法です。この機能は、Single Abstract Method (SAM) の概念と一致しており、単一の未実装メソッドを持つインターフェイスを Lambda 互換として扱うことができます。
ラムダ構文:
ラムダ式は通常、次の 3 つの部分で構成されます。
(parameters) -> expression (parameters) -> { statements; }
(int x, int y) -> x + y
(String message) -> System.out.println(message)
Java のラムダ式の構文は柔軟かつ直観的であるため、開発者は、複数行のコードが必要な場合に、簡潔なワンライナー形式か、より詳細なブロックのいずれかを選択できます。
Java 8 より前では、Runnable や Comparator などのインターフェイスを実装するには匿名の内部クラスが必要でした。ラムダ式はこのプロセスを合理化し、定型コードをより機能的なスタイルに置き換えます。以下は、ラムダ式が一般的なタスクをどのように簡略化するかを比較したものです:
例 1: Runnable でのラムダ式の使用
単純な Runnable 実装を考えてみましょう。匿名の内部クラスを使用すると、次のようになります:
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello world one!"); } };
ラムダ式を使用すると、このコードは次のように簡略化できます。
(parameters) -> expression (parameters) -> { statements; }
Java 8 では、java.util.function パッケージに事前定義された関数インターフェイスのセットが導入されています。これらのインターフェイス (述語、関数、コンシューマー、サプライヤーなど) はラムダ式の基盤を提供し、開発者が関数型プログラミングの原則を活用できるようにします。
これらのインターフェイスを Lambda 式で使用することにより、Java 開発者は簡潔なだけでなく、再利用性の高い操作を実行できます。
ラムダ式の動作を確認するために、ラムダ式がどのように冗長な構文を置き換え、一般的な操作を合理化し、読みやすさを向上させるかを示すいくつかのシナリオを見てみましょう。
Java の Runnable インターフェイスは、スレッドによって実行できるタスクを表します。このクラスは、run という引数のないメソッドを定義する必要があります。 Lambda 式が Runnable 実装を簡素化する方法を次に示します。
匿名の内部クラスで実行可能:
(int x, int y) -> x + y
ラムダ式で実行可能:
(String message) -> System.out.println(message)
ラムダ式を使用すると、5 行のコードが 1 行に減り、Java コードがいかに簡素化されるかが強調されます。
Comparator インターフェイスは、コレクションの並べ替えロジックを定義するためによく使用されます。ラムダ式を使用すると、カスタム並べ替え基準の定義がより簡潔かつ直感的になります。
人物のリストを姓で並べ替えるためのコンパレータ:
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello world one!"); } };
ラムダ式を使用すると、比較ロジックを変更することで並べ替え順序を簡単に切り替えることができます (降順など)。
Runnable r2 = () -> System.out.println("Hello world two!");
このアプローチは、動的並べ替えを必要とするアプリケーションで特に役立ち、開発者がユーザー入力やその他の条件に基づいて並べ替え基準を簡単に交換できるようになります。
GUI プログラミングでは、ユーザー アクションを処理するためにイベント リスナーが一般的に使用されます。従来は、匿名の内部クラスが必要であったため、コードが長くなってしまいました。ただし、ラムダ式は、これらのリスナーを実装するためのよりクリーンな方法を提供します。
匿名内部クラスを持つ ActionListener:
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Running with anonymous inner class"); } }; r1.run();
ラムダ式を使用した ActionListener:
(parameters) -> expression (parameters) -> { statements; }
ラムダ式を使用すると、開発者は ActionListener を 1 行で直接実装できるため、可読性が向上し、定型コードが削減されます。
ソフトウェア アプリケーションの一般的なシナリオは、複数の基準に基づいてデータをフィルタリングすることです。 Java では、ラムダ式と Predicate インターフェイスを組み合わせることでこれを効果的に処理でき、コレクションの動的フィルタリングが可能になります。
年齢や性別などのさまざまな基準に基づいてフィルタリングしたい、人物オブジェクトのリストについて考えてみましょう。
述語ベースの SearchCriteria クラスの定義:
(int x, int y) -> x + y
SearchCriteria クラスは、リストをフィルタリングするための一般的な条件をカプセル化し、単一のコレクションにさまざまなフィルタを柔軟に適用できるようにします。
フィルタリングでの基準の使用:
(String message) -> System.out.println(message)
このアプローチにより、複数の for ループが不要になり、よりクリーンで再利用可能、より保守しやすいソリューションが提供されます。
Java 8 の Stream API は、特に効率的なデータのフィルタリング、変換、集計を可能にする Lambda 式を使用して、コレクションの処理方法に革命をもたらします。ストリームを使用すると、必要な場合にのみデータが処理される遅延処理が可能になり、大規模なデータセットのパフォーマンスが向上します。
Stream API の forEach メソッドは、従来の for ループの代替手段を提供し、コレクション内の各要素にラムダ式を適用できるようにします。以下は、Person オブジェクトのリストを反復処理する例です。
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello world one!"); } };
メソッド参照の使用:
既存のメソッドを再利用できる場合、Java では、読みやすさを向上させる省略表現であるメソッド参照が許可されています。
Runnable r2 = () -> System.out.println("Hello world two!");
Stream API を使用すると、操作を連鎖させることができるため、開発者は 1 つのステートメントで結果をフィルタリング、マッピング、収集できます。
例: フィルタリングと収集:
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Running with anonymous inner class"); } }; r1.run();
このコードは、SearchCriteria クラスで定義された条件を使用して、18 ~ 25 歳の男性のみをフィルターします。
マップを使用したマッピングと変換:
map メソッドは、プロパティを抽出または変更するなどして、コレクション内の各要素を変換します。
Runnable r2 = () -> System.out.println("Running with Lambda Expression"); r2.run();
計算にマップを使用する:
mapToInt メソッドと mapToDouble メソッドは数値計算に役立ちます。
(parameters) -> expression (parameters) -> { statements; }
ストリームは遅延操作と積極的な操作をサポートしており、遅延操作 (フィルターなど) は必要な場合にのみ適用されます。この遅延により、必要な要素のみを処理することでパフォーマンスが最適化されます。
遅延評価の例:
(int x, int y) -> x + y
年齢が 30 歳を超える人のみが処理され、姓が出力され、遅延フィルタリングが示されています。
Java のParallelStream メソッドはタスクを複数のスレッドに分散し、大規模なデータ セットのパフォーマンスを大幅に向上させます。
並列ストリームの例:
(String message) -> System.out.println(message)
並列処理によりワークロードが分割され、計算負荷の高いタスクのコレクション操作が高速化されます。
ストリームは本質的に不変であるため、結果を保持するには結果を収集する必要があります。 collect メソッドは、ストリーム操作の結果を集約して保持する方法を提供します。
例:
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello world one!"); } };
ここでは、フィルタリングされた結果がさらなる処理のためにリストに保存され、開発者が構造化された方法で複雑なデータ フローを管理できるようになります。
Java 8 の Lambda 式と Stream API を組み合わせると、関数型プログラミングへの大きな変化が表れ、コードがより簡潔で表現力豊かになり、保守しやすくなります。匿名内部クラスの置き換え、コレクション処理の強化、並列操作のサポートにより、ラムダ式は最新の Java アプリケーションを作成するための基礎となりました。
この投稿に対する修正や追加は大歓迎です。
読んでいただきありがとうございます!
Runnable r2 = () -> System.out.println("Hello world two!");
以上がJava でラムダ式をマスターするための包括的なガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。