Lambda

lambda表达式(jdk1.8)

函数编程思想

描述

  强调的是作生么,而不是以什么样的方式来做,它忽略了面向对象的复杂语法,只要能够获取到结果,谁去做,怎么做的,都不重要重要的是结果,不重视过程。

冗余的Runnable代码

//传统的写法
public class Demo{
    public static void main(String[] args){
        //匿名内类的格式
        new Thread(new Runnable(){
            @Override
            public void run(){
                System.out.pringln("开启了一个新线程任务");
            }
        }).start();
    }
}
//对于Runnable的匿名内部类用法,可以分析一下内容:
 Thread类需要Runnable接口作为参数,其中的抽象方法run用来指定线程任务内容的核心。
 为了指定run方法的方法体,不得不需要Runnable接口的实现类。
 为了省去定义一个Runnable Impl实现类的麻烦,不得不使用匿名内部类。
 必须重写抽象方法run,所以方法的名称,参数返回值不得不再写一遍,且不能写错。
 从这里看出来,'只有方法体才是线程任务的关键性内容'。

编程思想的转换

  强调的是做什么,而不是怎么做

  我们希望做的事情是,将run方法内的代码传递给Thread类知晓能够加载即可。

传递代码  --》这是我们真正的目的

  我们需要将程序的重点从怎么做回归到做什么本质上,过程于形式不重要。

  2014年Oracle官方发布java 8 中,加入了Lambda表达式,可以取代大部分的匿名内部类,写出更优雅的代码

//优化刚才的代码
new Thread(() -> {
    System.out.println(Thread.currentThread().getName() + "-->");
}).start();
// 省略模式需要三项一起省略{} ;
new Thread(() -> System.out.println(Thread.currentThread().getName()+ "-->")).start();
//冲上面代码看出;没有创建实现类对象的操作,也不再有抽象方法覆盖重写的操纵,只写了线程的任务内容。

Lambda语法

  ()->System.println("开启了一个新线程");

   ()前面的一对小括号即为run方法,参数为空,里面的时空,此时需要任何的条件

   -> 中间的一个箭头宝石前面的参数传递给后面的代码

   {} 后面的输出语句即为业务逻辑代码(线程任务代码)

Lambda标准格式

  格式由三部分组成

  一些参数

  一个箭头

  一段代码

  (参数类型1,参数名称1,参数类型2,参数名称2...) ->{代码语句}

  格式说明

    小括号内的语法与传统的方法参数列表一致,无参数就留空,多个参数则用参数则用逗号隔开。

    -> 是新引入的语法格式,代表指向的动作。

    大括号的语法与传统方法要求一致。

横批:能省则省

左联: 左右遇一括号省

右联: 左侧推断类型省

使用Lambda格式练习

//(无参无返)
public class LambdaDemo4 {
    public static void main(String[] args) {
        //参数被省略了
        ad(()-> System.out.println(12));
    }
    //用一个方法采用
    public static void ad(AA aa) {
        aa.show();
    }
}
interface AA {
    void show();
}
***************************************************************************************************************
//(有参有返)
public class LambdaDemo3 {
    public static void main(String[] args) {
        //Lambda表达式
        invokeSum(3.2, 2.2, (double a, double b) -> {
            //带有返回值
            return a + b;
        });
        //采用匿名内部类写法
        invokeSum(3.2, 2.2, new Calc() {
            @Override
            public double sum(double a, double b) {
                return 3.2 + 2.2;
            }
        });
    }
    //定义方法
    //参数 传递两个double值
    // 传递一个calc接口方法
    // 内部调用了sum方法
    public static void invokeSum(double a, double b, Calc calc) {
        double sum = calc.sum(a, b);
        System.out.println(sum);
    }
}
//定义一个结算器,内置了一个抽象方法sum(d d1,d d2)
interface Calc {
    //定义一个求和的方法
    double sum(double a, double b);
}

练习

public class LambdaDemo6 {
    public static void main(String[] args) {
      /* 语法形式为 () -> {}
         其中 () 用来描述参数列表
         {} 用来描述方法体
         -> 为 lambda运算符 ,读作(goes to)。
         */
        //1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
        N1 n1 = (int a, int b) -> {
            System.out.println("多参无返被调用,他们的何为" + (a + b));
        };
        n1.method(12, 34);
        //-------------------------------------------------------
        //2.简化参数小括号,如果只有一个参数则可以省略参数小括号
        N2 n2 = () -> {
            System.out.println("无参无返方法被调用");
        };
        n2.method();
        //-------------------------------------------------------
        //3.简化方法体大括号,如果方法只有一条语句,则可以省略方法的大括号
        N3 n3 = (int a) -> {
            System.out.println("有一参无返被调用了," + a);
        };
        n3.method(13);
        //-------------------------------------------------------
        //4.如果方法体只有一条语句,并且是return语句,则可以省略方法体的大括号
        R4 r4 = (int a, int b) -> {
            return a - b;
        };
        System.out.println("多参有返被调用了," + r4.method(34, 21));
        //-------------------------------------------------------
        R5 r5 = () -> {
            return 12;
        };
        System.out.println("无参有返被调用了," + r5.method());
        //-------------------------------------------------------
        R6 r6 = (int a) -> {
            return a;
        };
        System.out.println("一个参数有返被调用了" + r6.methon(12));
    }
}

//多参数无返会
interface N1 {
    void method(int a, int b);
}

//无参无返回值
interface N2 {
    void method();
}

//一个参数无返回
interface N3 {
    void method(int a);
}

//多个参数有返回值
interface R4 {
    int method(int a, int b);
}

//无参有返回
interface R5 {
    int method();
}

//一个参数有返回值
interface R6 {
    int methon(int a);
}

Lambda省略格式

//可推导即可省略
//Lambda强调的是做什么,而不是怎么做,凡是可以根据上下文推到得知的信息,都可以省略。
invokeSum(3.14,3.15,(double a,double b)->{
    return a+b;
});
//省略格式
invokeSum(3.14,3.15,(a,b) -> a+b);
//在Lambda标准表达式省略规则;
    1.小括号内参数的类型可以省略。
    2.如果小括号内有且仅有一个参数,则小括号也可以省略。
    3.如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号,return关键字和语句的分号。

Lambda的使用前提

  Lambda的语法非常间接,使用非常间的简单,但是有一下注意事项

  1.使用Lambda必须有接口,并且要求仅有一个抽象方法

  2.使用Lambda必须具有上下文推断。

当有且仅有一个抽象方法的接口,称为函数接口

原文地址:https://www.cnblogs.com/zk2020/p/14126992.html