Lambda式がJDK 8に追加される前は、C#やC ++などの言語で使用していました。 Javaに追加されたとき、私はそれらをより詳細に研究し始めました。
Lambda式の追加により、Javaの「表現力」を高める構文要素が追加されました。 この記事では、Lambda式の使用を開始するために慣れる必要がある基本概念に焦点を当てたいと思います。
簡単な紹介
Lambda式は、マルチコア環境での並列プロセスを利用します。これは、Stream APIでデータパイプラインを使用した操作をサポートするときに明らかです。
これらは、機能インターフェイスによって定義されたメソッドを実装するために使用される匿名メソッド(名前のないメソッド)です。 Lambda式の使用を開始する前に、機能的なインターフェースとは何かを知ることが重要です。
機能的インターフェース
機能的インターフェースは、抽象メソッドを1つだけ含むインターフェースです。
標準のRunnableインターフェースの定義を見ると、run()という1つのメソッドのみを定義しているため、機能インターフェースの定義にどのように分類されるかがわかります。
以下のコード例では、
computeName
メソッドは
MyName
インターフェースの抽象的で唯一のメソッドであり、これが機能するインターフェースになります。
interface MyName{ String computeName(String str); }
演算子の矢印
ラムダ式は、Javaで新しい矢印
->
演算子を導入します。 ラムダ式を2つの部分に分割します。
(n) -> n*n
左側の部分は、式に必要なパラメーターを設定します。 パラメーターが不要な場合、この部分は空になります。
右側は、アクションを定義する式の本体です。
これで、関数式と矢印演算子を使用して、ラムダ式を簡単に作成できます。
interface NumericTest { boolean computeTest(int n); } public static void main(String args[]) { NumericTest isEven = (n) -> (n % 2) == 0; NumericTest isNegative = (n) -> (n < 0); // Output: false System.out.println(isEven.computeTest(5)); // Output: true System.out.println(isNegative.computeTest(-5)); }
interface MyGreeting { String processName(String str); } public static void main(String args[]) { MyGreeting morningGreeting = (str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (str) -> "Good Evening " + str + "!"; // Output: Good Morning Luis! System.out.println(morningGreeting.processName("Luis")); // Output: Good Evening Jessica! System.out.println(eveningGreeting.processName("Jessica")); }
上記の例では、それぞれ6行目と7行
morningGreeting
の変数
morningGreeting
と
eveningGreeting
が
MyGreeting
インターフェイスへのリンクを作成し、2つの挨拶表現を定義しています。
ラムダ式を作成するとき、次の例のように、パラメーターのタイプを明示的に指定できます。
MyGreeting morningGreeting = (String str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (String str) -> "Good Evening " + str + "!";
ラムダブロック
これまで、私は単一のラムダ式を見てきました。 複数の単純式と、矢印演算子の右側にあるいわゆるラムダブロックがある場合、別のタイプの式があります。
interface MyString { String myStringFunction(String str); } public static void main (String args[]) { // Block lambda to reverse string MyString reverseStr = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Output: omeD adbmaL System.out.println(reverseStr.myStringFunction("Lambda Demo")); }
汎用機能インターフェース
ラムダ式はジェネリックではない場合がありますが、式に関連付けられた機能インターフェイスは可能です。 共通のインターフェイスを1つ記述し、次のようなさまざまなデータ型を返すことができます。
interface MyGeneric<T> { T compute(T t); } public static void main(String args[]){ // String version of MyGenericInteface MyGeneric<String> reverse = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Integer version of MyGeneric MyGeneric<Integer> factorial = (Integer n) -> { int result = 1; for(int i=1; i <= n; i++) result = i * result; return result; }; // Output: omeD adbmaL System.out.println(reverse.compute("Lambda Demo")); // Output: 120 System.out.println(factorial.compute(5)); }
ラムダ式を引数として使用する
lambdaの一般的な使用法の1つは、引数として渡すことです。
実行可能コードをパラメーターとしてメソッド引数に渡すことができます。 これを行うには、機能インターフェースのタイプが必須パラメーターと互換性があることを確認してください。
interface MyString { String myStringFunction(String str); } public static String reverseStr(MyString reverse, String str){ return reverse.myStringFunction(str); } public static void main (String args[]) { // Block lambda to reverse string MyString reverse = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Output: omeD adbmaL System.out.println(reverseStr(reverse, "Lambda Demo")); }
これらの概念は、ラムダ式を開始するための優れた基盤となります。 コードを見て、どこで使用できるかを確認してください。