首页 > 技术文章 > Lambda表达式

superlsj 2019-10-10 17:17 原文

在Java1.8以后,推出了函数式编程的解决方案。初学几个月的朋友一定对这样:() -> {} 的东西恐惧又陌生。这是啥呀,这怎么用啊?

一、函数式编程:拷贝小括号,写死右箭头,落地大括号!!!

  在介绍Lambda表达式之前,先来了解一下函数式接口。所谓的函数式接口,就是接口中只有一个抽象方法。在8版本更新以后,接口中允许出现default方法和static方法。也就是说函数式接口中允许一个抽象方法,若干个default方法或者static方法。

  你可能使用过Runnable接口:

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

  这就是函数式接口,符合只有一个接口的规范。你可能也见过别人这么定义一个线程:

 new Thread(() -> {
   //run方法的业务
}).start();

  初次接触我也很排斥,可能是这破坏了某种编程习惯,但你相信我,当你会使用她以后,你会深深爱上她。

  上面我们说一个函数式接口中只有一个抽象方法,在使用Lambda表达式中的() -> {}就是对此抽象方法的实现。()就是抽象方法名后面的括号,有参数连带参数一起粘贴就行:(形参)。而  ->  是写死的运算符。那么 { 业务逻辑 }  其实就是对抽象方法的实现。而@FunctionalInterface注解就是显示的指定这是一个函数式接口,当你给一个接口加上@FunctionalInterface注解后,如果你给此接口定义两个抽象方法,那么编译器就会报错。

  所以这段代码:new Thread(() -> {}).start;  其中高亮部分就等价于new Runnable(public void run(){}),如果你用Lambda表达式创建线程,会比使用传统抽象类的方法省去不少功夫。

二、案例:

 

@FunctionalInterface
interface Foo{
    public int add(int x,int y);

    default int mul(int x,int y ){
        return x*y;
    }
    static int div(int x,int y ){
        return x/y;
    }
}

public class LambdaExpressDemo02 {
    public static void main(String[] args) {
//        Foo foo = new Foo() {
//            @Override
//            public int add(int x, int y) {    接口中的唯一的方法
//                return x+y;
//            }
//        };
        Foo foo =  (int x,int y) -> {return x+y; };

        System.out.println(foo.add(3,5));
        System.out.println(foo.mul(3,5));
        System.out.println(Foo.div(15,5));
    }
}

 

  (int x,int y)  ->  { return x+y; };,等价于 new Foo() { public int add( int x, inty )  { return x+y; } }。并且案例中也演示了定义和使用接口的default方法和static方法(default方法由接口的实例调用,static有接口自身调用)。

   所以Lambda其实就这么简单,记住口诀就行了:拷贝小括号,写死右箭头,落地大括号

  1、先把接口的抽象方法名后面的 () 连带形参一起粘贴过来。

  2、-> 固定写死

  3、{抽象方法的实现}

想到到这里我只要稍微一提:为什么函数式接口只能有一个抽象方法?因为定义多了他就不能唯一确定是去实现哪一个方法了啊!

推荐阅读