看看Lambda和方法引用吧~

150 阅读3分钟

「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

一、Lambda

简述:

Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。

1. 举例:(o1,o2) -> Integer.compare(o1,o2);

2. 格式说明:

  • -> :是Lambda操作符或箭头操作符。

  • ->左边: 书写Lambda形参列表(其实就是接口中的抽象方法的形参列表)。

  • ->右边: 书写Llambda体(其实就是重写的抽象方法的方法体)。

3. Lambda表达式的使用(分为6种情况介绍)

格式一:无参,无返回值。

常规写法:

    Runnable r1 = new Runnable() {
        @Override
        public void run() {
            System.out.println("我爱中国!");
        }
    };
    r1.run();

Lambda写法:

    Runnable r2=() -> System.out.println("Lambda,我爱中国!");
    r2.run();

看效果:

image.png

格式二:需要一个参数,但是没有返回值。

常规写法:

    Consumer<String> con1=new Consumer<String>() {
        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    };
    con1.accept("abcd");

Lambda写法:

    Consumer<String> con2=(String s)->System.out.println(s);
    con2.accept("Lambda,abcd");

看效果:

image.png

格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”。

将格式二中的Lambda写法小括号中参数类型去掉后

    Consumer<String> con2=(s)->System.out.println(s);
    con2.accept("Lambda,abcd");

看效果:

image.png

格式四:只需要一个参数时,参数的小括号可以省略。

再次将格式三中的Lambda写法小括号去掉后

    Consumer<String> con2=s->System.out.println(s);
    con2.accept("Lambda,abcd");

看效果:

image.png

格式五:需要两个或以上的参数,多条执行语句,并且可以有返回值。

常规写法:

Comparator<Integer> comparator=new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        System.out.println(o1);
        System.out.println(o2);
        return Integer.compare(o1,o2);
    }
};
System.out.println("传统写法:"+comparator.compare(12, 22));

Lambda写法:

    Comparator<Integer> comparator1 = (o1, o2) -> {
        System.out.println(o1);
        System.out.println(o2);
        return Integer.compare(o1,o2);
    };
    System.out.println("Lambda写法:"+comparator1.compare(33, 10));

看效果:

image.png

格式六:当Lambda体只有一条语句时,return 与大括号若有,都可以省略。

常规写法:

    Consumer<String> consumer=new Consumer<String>() {
        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    };
    consumer.accept("abcd");

Lambda写法:

    Consumer<String> consumer1= s -> System.out.println(s);
    consumer1.accept("zxcvb");

看效果:

总结:

  • ->左边: Lambda形参列表的参数类型可以省略(类型推断);如果Lambda形参列表只有一个参数,则()也可以省略。
  • ->右边: Lambda体应该使用一对{}包裹;如果Lambda体只有一条执行语句(可能是return语句),省略这一对{}和return。

4. Lambda表达式的本质其实是作为接口的实例

二、方法引用的使用

  • 使用情境:

    • 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
  • 方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例。所以方法引用,也是函数式接口的实例。

  • 使用格式:类(或对象)::方法名

  • 具体分为如下的三种情况:

    • 对象::非静态方法
    • 类::静态方法
    • 类::非静态方法
  • 方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!

简单使用(分为三种情况)

情况一:对象::实例方法

Lambda写法:

    Consumer<String> con1=str->System.out.println(str);
    con1.accept("北京");

方法引用:

    PrintStream ps=System.out;
    Consumer<String> con2=ps::println;
    con2.accept("南京");

看效果:

image.png

情况二:类::静态方法

Lambda写法:

    Comparator<Integer> comparator=(t1, t2)-> Integer.compare(t1,t2);
    System.out.println(comparator.compare(11, 22));

方法引用:

    Comparator<Integer> comparator1=Integer::compare;
    System.out.println(comparator1.compare(23, 5));

看效果:

image.png

情况三:类 :: 实例方法 (有难度)

Lambda写法:

Comparator<Integer> con1=(t1,t2)-> t1.compareTo(t2);
System.out.println(con1.compare(12, 50));

方法引用:

Comparator<Integer> con2=Integer::compareTo;
System.out.println(con2.compare(55, 36));

看效果:

image.png

本文到此结束!希望Lambda和方法引用的强大能对你有所影响。