进阶JAVA篇-深入理解Lambda表达式及其省略规则

目录

        1.0 什么是 Lambda 表达式?

        1.1 既然跟匿名内部类相关,先来回顾匿名内部类。

         1.2 Lambda 表达式与匿名内部类之间的关系。

        1.3 函数式接口

        1.4 在具体代码中来操作一下

        2.0 Lambda 表达式省略规则


        1.0 什么是 Lambda 表达式?

        Lambda 表达式是一种匿名函数,它可以在代码中以简洁的方式表示一个功能或行为。Lambda 表达式通常由参数列表、箭头符号和函数体组成。参数列表定义了该函数接受的输入参数,箭头符号表示函数体的开始,函数体则定义了函数的具体实现。Lambda 表达式可以作为一个整体被传递给其他函数或方法,也可以直接被调用。

        1.1 既然跟匿名内部类相关,先来回顾匿名内部类。

        匿名内部类是一种在Java中定义匿名类的方式。它允许在创建对象的同时定义该对象的类,并且不需要为该类单独命名。通常情况下,我们需要先定义一个类,然后才能创建该类的对象。但是在某些场景下,我们只需要定义一个临时的类来实现某个接口或继承某个类的功能,这时就可以使用匿名内部类。简单的理解就是减少了新类型的出现。

         1.2 Lambda 表达式与匿名内部类之间的关系。

        Lambda 表达式用于简化匿名内部类的代码写法。

代码如下:

未用 Lambda 表达式进行简化匿名内部类。

public class Text_Lambda {
    public static void main(String[] args) {


        Animal cat = new Animal(){
            @Override
            public void fun() {
                System.out.println("是只猫");
            }
        };

        Animal dog = new Animal() {
            @Override
            public void fun() {
                System.out.println("是只狗");
            }
        };

        cat.fun();
        dog.fun();

    }
}

interface Animal{
    public void fun();
}

运行结果如下:

用 Lambda 表达式进行简化匿名内部类。

public class Text_Lambda {
    public static void main(String[] args) {


/*        Animal cat = new Animal(){
            @Override
            public void fun() {
                System.out.println("是只猫");
            }
        };*/
        //下面用Lambda表达式简化的代码跟上面的代码式等效的
        Animal cat = () -> {
                System.out.println("是只猫");
            };


/*        Animal dog = new Animal() {
            @Override
            public void fun() {
                System.out.println("是只狗");
            }
        };*/
        //下面用Lambda表达式简化的代码跟上面的代码式等效的
        Animal dog = () -> {
                System.out.println("是只狗");
            };

        cat.fun();
        dog.fun();

    }
}
interface Animal{
    public void fun();
}

运行结果如下:

        再简单小结一下,Lambdab 表达式存在的意义就是简化匿名内部类,具体格式为 (被重写方法的形参列表)-> {(被重写方法的方法体)}

        1.3 函数式接口

        现在知道 Lambda 表达式可以简化匿名内部类,但是需要注意的是,并不是所有的匿名内部类都可以用 Lambda 表达式进行简化的,只有函数式接口才可以被 Lambda 表达式简化。

        什么是函数式接口?

        函数式接口是指只包含一个抽象方法的接口。在Java中,函数式接口是支持函数式编程的基础,它可以用作 Lambda 表达式的目标类型。

        Java 8引入了@FunctionalInterface注解,用于标识一个接口为函数式接口。编译器会检查被标注的接口是否符合函数式接口的定义,如果不符合,编译器会报错。

如:

        总的来说,如果是接口并且只包含了一个抽象方法,或者引用了 @FunctionalInterface注解的时候都为函数式接口,都可以被 Lambda 表达式简化。

        1.4 在具体代码中来操作一下

               例子 1.0 :

        回顾在介绍到 Arrays 类中的 sort() 静态方法中其中有一个参数就是匿名内部类。

这个方法具体的介绍在此链接:

进阶JAVA篇-如何理解作为参数使用的匿名内部类与 Arrays 类的常用API(九)-CSDN博客

        如果想要把这个匿名内部类用 Lambada 表达式进行简化,就想要了解它是否为函数式接口。

该匿名内部类引用了@FunctionalInterface注解,因此,它可以被 Lambda 表达式简化。

用 Lambda 表达式简化匿名内部类代码如下: 

import java.util.Arrays;

public class ArraysAPI {

    public static void main(String[] args) {
        Student[] students = new Student[4];
        students[0] = new Student("张三",32);
        students[1] = new Student("李四",21);
        students[2] = new Student("王五",20);
        students[3] = new Student("赵六",22);

/*        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                if (o1.getAge()> o2.getAge()){
                    return 1;
                } else if (o1.getAge()< o2.getAge()) {
                    return -1;
                }
                return 0;
            }
        });*/
        Arrays.sort(students,(Student o1, Student o2)-> {
                if (o1.getAge()> o2.getAge()){
                    return 1;
                } else if (o1.getAge()< o2.getAge()) {
                    return -1;
                }
                return 0;
            });
        System.out.println(Arrays.toString(students));
    }
}

提醒一下,以上该代码省略了 Student 类。

运行结果如下:

        已经用 Lambda 表达式进行简化的代码与被屏蔽的代码(未用 Lambda 表达式进行简化)相对比,确实式简化了很多。

               例子 2.0 :

        回顾在介绍到 Arrays 类中的 setAll() 静态方法中其中一个参数为匿名内部类。

 这个方法具体的介绍在此链接:

进阶JAVA篇-如何理解作为参数使用的匿名内部类与 Arrays 类的常用API(九)-CSDN博客

        同样的, 如果想要把这个匿名内部类用 Lambada 表达式进行简化,就想要了解它是否为函数式接口。

很显然,这个引用了@FunctionalInterface注解,因此,它可以被 Lambda 表达式简化。

 用 Lambda 表达式简化匿名内部类代码如下: 

import java.util.Arrays;

public class ArraysAPI {
    public static void main(String[] args) {
        double[] arr = new double[]{1.0,2.0,9,4.0,5.0};
/*        Arrays.setAll(arr, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int value) {
                return arr[value] * 0.8;
            }
        });*/
        Arrays.setAll(arr, (int value) ->{
                return arr[value] * 0.8;
            });
        System.out.println(Arrays.toString(arr));
        
    }
}

运行结果如下:

        2.0 Lambda 表达式省略规则

        通过以上的讲解,现在知道函数式接口是可以通过 Lambda 表达式简化的,那么还能不能更进一步简化呢?

        答案肯定是无容置疑的,可以继续简化。

        具体来介绍省略的规则:

        1. 参数类型可以省略不写。

        2.  如果只有一个参数的,参数类型可以省略不写,同时()也可以不写。

        3. 如果重写的方法体只有一行代码,可以省略大括号不写,同时要省略分号!此时,如果这行代码是 return 语句,也必须去掉 return 语句。

代码如下:

import java.util.Arrays;

public class ArraysAPI {
    public static void main(String[] args) {
        double[] arr = new double[]{1.0,2.0,9,4.0,5.0};

        //第一代的样子
/*        Arrays.setAll(arr, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int value) {
                return arr[value] * 0.8;
            }
        });*/

        //第二代的样子
/*        Arrays.setAll(arr, (int value) ->{
                return arr[value] * 0.8;
            });*/

        //第三代的样子
        Arrays.setAll(arr,value ->arr[value] * 0.8 );
        System.out.println(Arrays.toString(arr));

    }
}

运行结果如下:

        此时你是不是嘴巴都张大了? 正常,当时的我也是这样的。其实这还不最简化的表达式,还可以更加深入简化!!!这就是好奇心推动我们不断学习的源源不断的动力!

                                                ​​​​​​​本篇先介绍到这!!! 



物联沃分享整理
物联沃-IOTWORD物联网 » 进阶JAVA篇-深入理解Lambda表达式及其省略规则

发表评论