vlambda博客
学习文章列表

函数式编程和lambda

最近看到了java14出来了,想到java8中的东西还没怎么用过,就又复习了一遍。


一,面向对象到函数式编程


我们平常写的java代码都是面向对象编程,它是一个概念,在java中的实现就是封装,继承,多态。


同样的,函数式编程也是一个概念,在java中实现就是lambda(λ,在数学函数中经常见到,具体的忘光了)。


二 .从函数式编程到lambda


行为参数化,一个很抽象的概念,其实我们每天都在用,很像一种策略模式,如我们在js之中不断传入的回调函数一样。


在java8之中,函数式编程的根基就是lambda,这是整个java函数式编程的基础。

我们想在想做的就是引入lambda。


我们以前使用线程Runnable的方式:

Runnable runnable = new Runnable() { @Override public void run() { for(;;) System.out.println("thread is running..."); }  }; new Thread(runnable).start();

以前我们使用匿名内部类的方式来编写一个Runnbale的实现。其实在上面的代码之中,只有红色部分是有用的。


当我们编写了很多这样的代码之后,我们大概能够知道。我们其实就是想创建一种行为而已(或者说一种实现而已),根本没有必要每次都写大量的模板代码。


于是,我们可以用lambda写下面的代码:

new Thread(()->{ for(;;) System.out.println("thread is running..."); }).start();


三 .lambda表达式的本质


lambda表达式的本质和匿名内部类是一样的,而且它的条件更加苛刻。


下面的例子证明lambda和匿名内部类其实是一种事物:

Runnable run = ()->{            for(;;)                System.out.println("thread is running...");        };

看到上面的代码没有编译的问题了吗? 这就证明lambda本质上就是一个匿名内部类的实现而已。


从这里我们能够看到,即使java出现了lambda,从本质上还是没有推翻我们之前的世界观。


在上面,提到了lambda的条件更加苛刻,为什么呢?


我们知道,一个匿名内部类可以实现多个方法,但是lambda却只能实现一个.

因此,在java8之中为了更好地表达lambda的使用,出现了一个新的概念,就是函数式接口。


看到了吗,lambda和函数式接口出现了,函数式接口本身就是为了lambda服务的。


那么,什么是函数式接口呢?很简单,就是一个接口(抽象类)内部仅仅只有一个待实现的方法,我们就称为函数式接口。

为了表达这个概念,在java8之中使用一个注解表达这个概念,

public @interface FunctionalInterface {}

这个注解仅仅只是一个标记注解,能提供的作用仅仅是在编译之前指明语法错误,像@Override一样。

即使一个接口没有这个注解,也不会妨碍这个接口成为一个函数式接口。