欢迎光临散文网 会员登陆 & 注册

javaLambda表达式

2022-09-16 08:55 作者:虚云幻仙  | 我要投稿

/**
* Lambda表达式用于简化代码
* 函数式接口:只有一个抽象方法的接口,可以有其他默认方法
* Lambda表达式可用于简化匿名内部类的代码结构
*/

@FunctionalInterface
interface NoReturn0Parameter{
   //包含没有返回值,没有参数的抽象方法的函数式接口
   //在接口上方用注释@FunctionalInterface 来限制接口内只能有一个抽象方法,当有多个时报错

   void method();
   //抽象方法:返回值类型 方法名()
}
@FunctionalInterface
interface NR1P{
   //无返回1参数
   void method(int a);
}
@FunctionalInterface
interface NR2P{
   //无返回2参
   void method(int a,int b);
}
@FunctionalInterface
interface R0P{
   //有返回值无参
   int method();
}
@FunctionalInterface
interface R1P{
   //有返回1参
   int method(int a);
}
@FunctionalInterface
interface R2P{
   //有返回2参
   int method(int a,int b);
}
public class TestLambda1 {
   public static void main(String[] args) {
       NoReturn0Parameter noReturn0Parameter = new NoReturn0Parameter() {
           //匿名内部类通常写法
           @Override
           public void method() {
               System.out.println("TestLambda1.method");
           }
       };

       NoReturn0Parameter noReturn0Parameter1 = ()->{
           System.out.println("TestLambda1.main");
       };
       //Lambda表达式格式: (参数)->{方法体}
       //无参所以用(),{}方法体不用写声明的部分(public void method),因为函数式接口必须只有一个抽象方法,所以lambda实现的就是这个方法,所以省略了声明

       noReturn0Parameter1.method();
       //noReturn0Parameter1是实现类对象,引用类型是NoReturn0Parameter接口,实现了方法后可正常调用
       NR1P nr1P = (int a)->{
           System.out.println(a);
       };
       nr1P.method(20);
       NR2P nr2P = (int a,int b)->{
           System.out.println(a+b);
       };
       nr2P.method(20,30);

       R0P r0P = ()->{
           System.out.println("TestLambda1.main");
           return 10;
       };
       //有返回值则在方法体内写明
       int c = r0P.method();
       R1P r1P = (int a) -> {
           System.out.println("TestLambda1.main");
           return a;
       };
       R2P r2P = (int a, int b)->{
           System.out.println("TestLambda1.main");
           return a+b;
       };
   }
}
class TestLambda2{
   public static void main(String[] args) {
       //简写Lambda,()->{}是完整形式,代码可以再简化
       NoReturn0Parameter noReturn0Parameter = ()-> System.out.println("TestLambda2.main");
       //方法体{}只有一行代码时可以去掉{}
       NR1P nr1P = a-> System.out.println(a);
       //参数()只有一个参数时可以省略(),参数可以省略类型
       NR2P nr2P = (a,b)-> System.out.println(a+b);
       //只有在参数为一个时可以省略(),但可以省略类型
       R0P r0P = ()->20;
       //当方法体只有一句return 20 时将{}和return都省略
       R1P r1P = a->{
           System.out.println("TestLambda2.main");
           return a;
       };
       //当方法体有多行代码时{}和return都不能省略
       R2P r2P = (a,b)->a+b;
       //将{return a+b}简写为a+b

       //闭包问题
       int x = 20;
       NoReturn0Parameter noReturn0Parameter1 = new NoReturn0Parameter() {
           @Override
           public void method() {
               System.out.println(x);
           }
       };
       //匿名内部类为闭包的一种,在闭包中调用外部的变量,会将变量赋final属性,后续再对x进行更改的话内部类的x会报错,如果在内部类之前变量x就已经多次赋值了,在闭包中调用x会直接报错,lambda表达式简化匿名内部类代码,在表达式内调用外部变量同样会赋final属性
       //x++;报错

   }
}
class TestLambda3{
   //在Lambda中引入其他方法
   public static void print(int a){
       System.out.println(a);
   }
   public int times(int a,int b){
       return a*b;
   }

   public static void main(String[] args) {
       NR1P nr1P = a->TestLambda3.print(a);
       //使用已存在的方法来实现抽象方法
       nr1P = TestLambda3::print;
       //简写为 方法归属者::方法名
       //要求引入的方法和抽象方法的参数列表和返回值类型必须一致,而因为参数和返回值一致所以将()参数和return都省略了,->goes to运算符也省略了,而print静态方法属于类TestLambda3,所以写为类名::方法名

       R2P r2P = new TestLambda3()::times;
       //times方法属于对象,所以引用时需要写为 对象::方法名
       NR1P nr1P1 = System.out::println;
       //将 a->System.out.println(a);简写  println是属于对象out的
       R2P r2P1 = Integer::sum;
       //将 (a,b)->a+b; 改写为调用Integer.sum(int a,int b)方法
       //反过来说,将Integer.sum(int a,int b)方法的.换成:: 再去掉参数(int a,int b),写成Integer::sum


       //使用Lambda表达式创建线程
       Thread t1 = new Thread(new Runnable() {
           @Override
           public void run() {
               System.out.println("通常的匿名内部类");
           }
       },"匿名内部类线程");
       Thread t2 = new Thread(()->{
           System.out.println("因为new Thread()构造器中声明了参数类型为Runnable,Lambda表达式将引用类型变量 Runnable xxx= 省略,只写表达式的部分");
           System.out.println("Runnable接口内只有一个抽象方法run(),没有其他任何内容,即Runnable接口为函数式接口,适用Lambda");
       });

   }
}

javaLambda表达式的评论 (共 条)

分享到微博请遵守国家法律