前言
之前有一个小伙伴给我发了一段代码,说是看不懂,这段代码是这样的:
1 | public class Aha { |
如果屏幕面前的你也不是很能够理解,那就听我细讲吧。首先,在理解上述代码之前,我们需要了解一个概念-----函数式接口
。
函数式接口
函数式接口,指只定义了一个抽象方法的接口。
比如如下的接口便是一个最简单的函数式接口:
1 | interface Care{ |
如果你对jdk
的源码有过研究的话,会发现JDK
中也提供了许多函数式接口
,比如我们熟悉的 Runnable 接口和 Callable 接口:
细心的小伙伴会发现,上面两段源码中均对接口加上了一个注解:
@FunctionalInterface
,顾名思义,这表示该接口会被设计成一个函数式接口,不符合规范的话,编译时会报错。
再比如线程池中的 Executor 接口:
函数式接口的用处
那么问题来了,将接口设计成函数式接口有什么好处呢?
我们通过一个例子来领会它的妙处,首先,上一段简单的代码:
1 | public class Haha { |
相信学过接口的小伙伴们能够很轻松地看懂上面这段代码。
现在我们深入地想一想,如果ILike
这个接口仅仅是在Haha
这个类中使用,那我们没必要新建一个外部Like实现类
,一个很自然的想法便是将Like
实现类设计成静态内部类
:
1 | public class Haha { |
既然想到了设计成静态内部类
,为何不干脆设计成局部内部类
呢:
1 | public class Haha { |
进一步,如果你学过匿名内部类
的话,咱还可以把实现类的类名Like
省略,简化成:
1 | public class Haha { |
现在,我们来看核心代码:
1 | ILike iLike = new ILike() { |
上面这段代码,已经把实现接口的类的类名给省略了,我们想一想,还能不能省略点东西?
Lambda表达式
实际上,iLike
前面已有ILike
修饰,故后面的“new ILike
”字样完全可以省略,不会产生歧义。
而且,重点来了!!!由于ILike
本身是一个函数式接口
,它只有一个抽象方法 like()
,所以上面的代码中完全可以把重写的like()
方法中的“固定代码”去掉而不会产生歧义,甚至花括号也可以去掉,直接写成:
ILike iLike = () System.out.println ( " 我是易果啥笔 " ) ;
当然,在jdk8
(或更高)规范中,需要我们加上一个小箭头“ ->
”:
1 | ILike iLike = () -> System.out.println("我是易果啥笔"); |
到这,我们已经将一个复杂的代码块缩短成了最简单的一行代码,这种用“->
”符号来编写的表达式,便称为匿名表达式
,也叫Lambda表达式。
从上述过程可以看出,Lambda表达式
的优点在于能够使代码变得更为简洁。注意,能够将代码缩短至一行是有一定条件的,下面的代码列举的应该包含绝大多数情况了:
1 | //如果接口实现的语句不止一个,则必须加上花括号{},这与if,for,while语法类似: |
到这,本文最开始给出的那段代码就很好理解了,其实就是一个简单的Lambda表达式
而已:
1 | public class Aha { |
事实上,Lambda表达式
的应用远不止这些,有兴趣的小伙伴可以去查询更多的资料了解Lambda表达式
的其他应用。