ラムダ式 (クロージャ): Java8 の新機能で、ラムダはメソッドのパラメータとして関数を実行します。つまり、関数はパラメータとしてメソッドに渡されます。ラムダ式を使用すると、コードをより簡潔にすることができます。
ラムダ式の使用シナリオ: インターフェイスの実装を簡素化するために使用されます。
インターフェイスの実装に関しては、さまざまな実装方法があります。たとえば、インターフェイスの実装クラスを設計し、匿名の内部クラスを使用します。ただし、ラムダ式はこれらの方法よりも単純です。
package test; /** * @author: Mercury * Date: 2022/3/20 * Time: 17:48 * Description:Lambda表达式 * Version:1.0 */ public class Test04 { public static void main(String[] args) { //使用lambda表达式实现接口 Test test = () -> { System.out.println("test"); }; test.test(); } } interface Test{ public void test(); }
ラムダ式を使用すると、インターフェイスの実装をある程度簡素化できます。ただし、ラムダ式を使用してすべてのインターフェイスを簡潔に実装できるわけではありません。
結局のところ、ラムダ式は単なる匿名メソッドです。実装されたインターフェイスにメソッドが多すぎる場合、または多すぎる場合、ラムダ式は適用できません。
ラムダ式は関数型インターフェイスのみを実装できます。
インターフェイスでは、実装クラスが実装する必要がある抽象メソッドは 1 つだけです。このようなインターフェイスは機能インターフェイスです。
コードは次のとおりです (例):
//有且只有一个实现类必须要实现的抽象方法,所以是函数式接口 interface Test{ public void test(); }
はアノテーションであり、インターフェースの前で使用され、インターフェースは ⼼機能的なインターフェースです。機能的なインターフェースであれば問題ありません。機能するインターフェイスではない場合、エラーが報告されます。 @Override と同様の関数。
コードは次のとおりです (例):
@FunctionalInterface interface Test{ public void test(); }
ラムダ式、事実、本質 つまり、匿名関数です。したがって、ラムダ式を記述するときにメソッド名を気にする必要はありません。
実際、ラムダ式を作成するとき、戻り値の型を気にする必要はありません。
ラムダ式を記述するときは、パラメータ リストとメソッド本体の 2 つの部分に注意するだけです。
ラムダ式の基本構文:
(パラメータ 1, パラメータ 2,&hellip ;) -> {
メソッド本体
};
パラメータ部分: メソッドのパラメータリスト。実装されたインターフェースのメソッドパラメータ部分と一致している必要があります。パラメータとタイプ。
メソッドボディ部: メソッドの実装部分であり、インターフェースで定義したメソッドに戻り値がある場合は、戻り値に注意して実装してください。
-> : パラメータ部分とメソッド本体部分を分離します。
コード例:
package test; /** * @author: Mercury * Date: 2022/3/20 * Time: 17:48 * Description:Lambda表达式 * Version:1.0 */ public class Test04 { public static void main(String[] args) { //使用lambda表达式实现接口 //无参 // Test test = () -> { // System.out.println("test"); // }; //有参 // Test test = (name,age) -> { // System.out.println(name+age+"岁了!"); // }; // test.test("小新",18); //有参+返回值 Test test = (name,age) -> { System.out.println(name+age+"岁了!"); return age + 1; }; int age = test.test("小新",18); System.out.println(age); } } //无参 //interface Test{ // public void test(); //} //有参 无返回值 //interface Test{ // public void test(String name,int age); //} //有参 有返回值 interface Test{ public int test(String name,int age); }
パラメータ部分の簡略化
パラメータの種類
インターフェースメソッド内で各パラメータの型が定義されているためです。また、ラムダ式を使用してインターフェイスを実装する場合は、パラメーターの数と型がインターフェイス内のメソッドと一致していることを確認する必要があります。したがって、ラムダ式のパラメータの型はこの時点では省略できます。
注:
パラメータの型を省略する必要がある場合は、必ず次のことを確認してください。省略する場合は、各パラメータの型を省略し、記述しない必要があります。 。省略されるパラメータの種類と省略されないパラメータの種類があります。
//有参+返回值 Test test = (name,age) -> { System.out.println(name+age+"岁了!"); return age + 1; }; int age = test.test("小新",18); System.out.println(age);
パラメータの親
メソッドのパラメータ リストにパラメータが 1 つだけある場合、現時点ではパラメータ リストのかっこを次のように指定できます。省略しました。
注:
パラメータの数が 1 つの場合に限り、複数のパラメータを省略することはできません。
//一个参数 Test test = name -> { System.out.println(name+"test"); }; test.test("小新");
メソッド本体の簡略化
メソッド本体の中括弧の簡略化メソッド本体内のロジックに文が 1 つだけある場合、中括弧は省略できますTest test = name -> System.out.println(name+"test"); test.test("小新");
return 簡略化
メソッド内の唯一のステートメントが return ステートメントである場合、中括弧を省略するときは return も省略する必要があります。Test test = (a,b) -> a+b;
: 既存のメソッドを参照してラムダ式を置き換え、インターフェイスの実装を完了します1. 静的メソッドへの参照
構文: クラス::静的メソッド
注:package test; /** * @author: Mercury * Date: 2022/3/20 * Time: 18:17 * Description:lambda表达式静态方法引用 * Version:1.0 */ public class Test05 { public static void main(String[] args) { //实现多个参数,一个返回值的接口 //对一个静态方法的引用,语法:类::静态方法 Test1 test1 = Calculator::calculate; System.out.println(test1.test(4,5)); } } class Calculator{ public static int calculate(int a,int b ){ // 稍微复杂的逻辑:计算a和b的差值的绝对值 if (a > b) { return a - b; } return b - a; } } interface Test1{ int test(int a,int b); } package test; /** * @author: Mercury * Date: 2022/3/20 * Time: 18:17 * Description:lambda表达式静态方法引用 * Version:1.0 */ public class Test05 { public static void main(String[] args) { //实现多个参数,一个返回值的接口 //对一个静态方法的引用,语法:类::静态方法 Test1 test1 = Calculator::calculate; System.out.println(test1.test(4,5)); } } class Calculator{ public static int calculate(int a,int b ){ // 稍微复杂的逻辑:计算a和b的差值的绝对值 if (a > b) { return a - b; } return b - a; } } interface Test1{ int test(int a,int b); }
: オブジェクト::非静的メソッド
注意事項:
引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的⼀致。
package test; /** * @author: Mercury * Date: 2022/3/21 * Time: 8:14 * Description:lambda表达式对非静态方法的引用 * Version:1.0 */ public class Test06 { public static void main(String[] args) { //对非静态方法的引用,需要使用对象来完成 Test2 test2 = new Calculator()::calculate; System.out.println(test2.calculate(2, 3)); } private static class Calculator{ public int calculate(int a, int b) { return a > b ? a - b : b - a; } } } interface Test2{ int calculate(int a,int b); }
使用场景
如果某个函数式接口中所定义的方法只是为了获取一个类的对象。此时我们就可以使用构造方法的引用,简化这个方法的实现。
语法:类名::new
注意事项:可以通过接口中的方法的参数, 区分引用不同的构造方法。
package com.cq.test; /** * @author: Mercury * Date: 2022/4/27 * Time: 10:31 * Description:lambda构造方法的引用 * Version:1.0 */ public class Test { private static class Dog{ String name; int age; //无参构造 public Dog(){ System.out.println("一个Dog对象通过无参构造被实例化了"); } //有参构造 public Dog(String name,int age){ System.out.println("一个Dog对象通过有参构造被实例化了"); this.name = name; this.age = age; } } //定义一个函数式接口,用以获取无参的对象 @FunctionalInterface private interface GetDog{ //若此方法仅仅是为了获得一个Dog对象,而且通过无参构造去获取一个Dog对象作为返回值 Dog test(); } //定义一个函数式接口,用以获取有参的对象 @FunctionalInterface private interface GetDogWithParameter{ //若此方法仅仅是为了获得一个Dog对象,而且通过有参构造去获取一个Dog对象作为返回值 Dog test(String name,int age); } // 测试 public static void main(String[] args) { //lambda表达式实现接口 GetDog lm = Dog::new; //引用到Dog类中的无参构造方法,获取到一个Dog对象 Dog dog = lm.test(); System.out.println("修狗的名字:"+dog.name+" 修狗的年龄:"+dog.age); //修狗的名字:null 修狗的年龄:0 GetDogWithParameter lm2 = Dog::new;//引用到Dog类中的有参构造,来获取一个Dog对象 Dog dog1 = lm2.test("萨摩耶",2); System.out.println("修狗的名字:"+dog1.name+" 修狗的年龄:"+dog1.age);//修狗的名字:萨摩耶 修狗的年龄:2 } }
这⾥类似于局部内部类、匿名内部类,依然存在闭包的问题。
如果在lambda表达式中引用了局部变量,则该局部变量会隐式声明为final变量。是⼀个常量,不能修改值。
以上がJavaのラムダ式で使用されるメソッドは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。