Lambda表达式概念与基本语法

时间:2022-09-03 15:42:34

Lambda表达式是Java 8的重要更新,一个被广大开发者期待已久的新特性。Lambda表达式支持将代码块作为方法参数,Lambda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例。

//接口,用于封装处理行为。因为暂时无法确定处理行为,所以是空方法体
interface Command {
    void process(int[] target);
}

//处理数组
class ProcessArray {
    public void process( int[] target, Command cmd ) {
        cmd.process(target);
    }
}

public class Test {
    
    public static void main(String[] args) {
        ProcessArray pa = new ProcessArray();
        
        int[] target = {3,-4,6,4};
        
        pa.process(target, new Command() {
            public void process(int[] target) {
                int sum = 0;
                for( int tmp : target ) {
                    sum+=tmp;
                }
                System.out.println("Summary:"+sum);
            }
        });
    }
}

ProcessArray类的process()方法处理数组时,希望可以动态传入一段代码作为具体的处理行为,因此程序创建了一个匿名内部类实例来封装处理行为。但为了向process()方法传入这段代码,程序不得不使用匿名内部类的语法来创建对象。

Lambda表达式完全可用于简化创建匿名内部类对象,因此可将上面代码改为如下形式。

interface Command {
    void process(int[] target);
}

class ProcessArray {
    public void process( int[] target, Command cmd ) {
        cmd.process(target);
    }
}

public class Test {
    
    public static void main(String[] args) {
        ProcessArray pa = new ProcessArray();
        
        int[] array = {3,-4,6,4};
        
        pa.process(array,(int[]target)->{
            int sum = 0;
            for( int tmp:target ) {
                sum+=tmp;
            }
            System.out.println("Summary:"+sum);
        });
    }
}

从上面程序中可以看出,这与创建匿名内部类时需要实现的方法完全相同,只是不需要new Xxx(){}这种繁琐的代码,不需要指出重写的方法名字,也不需要给出重写的方法的返回值类型——只要给出重写的方法括号以及括号里的形参列表即可。

当使用Lambda表达式代替匿名内部类创建对象时,Lambda表达式的代码块将会代替实现抽象方法的方法体,Lambda表达式就相当于一个匿名方法。


小结

Lambda表达式的主要作用就是代替匿名内部类的繁琐语法。它由三部分组成。

  • 形参列表:形参列表允许省略形参类型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。

  • 箭头->

  • 代码块。如果代码块只包含一条语句,Lambda表达式允许省略代码块的花括号。代码块只有一条return语句,甚至可以省略return 关键字。Lambda表达式需要返回值,而它的代码块中仅有一条省略了return的语句,Lambda表达式会自动返回这条语句的值。

下面示范了Lambda表达式的几种简化写法。

interface Eatable {
    void taste();
}

interface Flyable {
    void fly( String weather );
}

interface Addable {
    int add(int a, int b);
}

public class Test {
    
    public void eat( Eatable e ) {
        System.out.println(e);
        e.taste();
    }
    
    public  void drive( Flyable f ) {
        System.out.println("我正在驾驶:"+f);
        f.fly("碧空如洗的晴日");
    }
    
    public void test (Addable add) {
        System.out.println("5+3="+add.add(5,3));
    }
    
    public static void main(String[] args) {
        Test t = new Test();
        
        //Lambda语句只有一条语句,可以省略花括号
        t.eat(()->System.out.println("苹果的味道不错!"));
        
        //只有一个形参,可以省略圆括号
        t.drive( weather-> {
            System.out.println("今天天气是:"+weather);
            System.out.println("直升机飞行平稳");
        });
        
        //只有一条语句,可以省略return
        t.test((a,b)->a+b);
    }
}