java8-01-lambda
0 lambda的传说
其实我也没法说清楚他到底是什么鬼……
就好比你没见过某种颜色,我再怎么描述都没法描述清楚,还是亲自看看他长啥样吧
还记得中学的时候,数学里经常出现的那个符号吗?
先放一个从百度图库偷来的图片(CSDN打上的水印,不关我事哈……)
就是这货,此处的lambda
就是它……
传说中这玩意儿是比程序员还疯狂的数学家的口头禅……
上面的废话都看完了????
虽然见到了他,但是还是不清楚他到底是什么……
好了,不扯皮了,开讲啦
- 百科里是这么描述的:
Lambda 表达式”是一个匿名函数,可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。
看百科的描述好像有那么点感觉了。可是干嘛非要搞个这么高冷的解释呢?
- 个人是这么理解的:
lambda 类似于一个可调用的代码块或者游离函数。当然也可以有入参。
1 瞄一眼他长啥样?
- 示例
比如下面这样:
|
|
等价的原始Java代码长这样:
|
|
用上lambda是什么体验?
- 代码量好像少了
- 逼格好像提高了
- 代码好像更优雅了
2 lambda各种外观
至少在Java里lambda的爸爸妈妈姐姐弟弟爷爷奶奶七大姑八大姨……可能都是长这个样子的。
同时,据老夫多年的断案经验来推断,lambda的本尊应该也是这个样子的:
|
|
- 外观一:没有入参的时候
|
|
- 外观二:有参数的时候
|
|
- 外观三:函数体只有一行的时候
|
|
- 外观四:没有返回值的时候
|
|
- 方法引用和构造器引用
- instance::instanceMethod
- className::staticMethod
- className::instanceMethod
|
|
- ……
3 lambda使用场景
再看一个例子:
|
|
不难看出,整个匿名内部类中最关键的代码其实就是:
|
|
所以,lambda中关键部分也就是这部分代码了。
其实,用注解java.lang.FunctionalInterface
修饰的接口都可以用于lambda表达式中。
这种接口,都是只有一个方法的接口。
另外,只要你的接口只有一个方法,即使是没有@FunctionalInterface
注解修饰,也是可以用lambda的(很多时候编译器还是很聪明的,他会自动推断的)。
总之,lambda只钟爱函数式接口(@FunctionalInterface
)。
4 再来个示例
|
|
- 有如下数据
|
|
- 按距离排序
|
|
- 输出小区名
|
|
- 动态条件过滤
|
|
- 字符串转大写
|
|
- 其实在Scala里lambda更加直观
|
|
5 lambda的好基友
通过上面的示例,再结合实际。不难发现最常用的lambda的形式如下:
- 单个输入,无输出
- 单个输入,单个输出
- 无输入,输出单个类型
- 两个不同类型的输入,第三种类型的输出
- 两个不同类型的输入,其中一种类型的输出
- ……
其实在每次使用的时候,没必要自己去新建这些函数式接口以支持lambda,JDK就已经给lambda内置了很多好基友:
- Consumer: 单个输入,无输出
|
|
- BiConsumer: 两个不同类型的输入,无输出
|
|
- Supplier: 无输入,输出单个类型
|
|
- Function: 两个不同类型的输入
|
|
- ToIntFunction / ToLongFunction / ToDoubleFunction
|
|
- IntFunction / LongFunction / DoubleFunction
|
|
- BiFunction: 两个不同类型的输入,第三种类型的输出
|
|
- 条件测试
|
|
可以不用自定义函数式接口来支持lambda,上面的例子可以改成:
|
|
关于lambda的传说和他到底是什么鬼,看到这里应该够了。
毕竟我们的主要目的是使用它,知道他怎么用才是重点。
没必要纠结他严格的学术定义(这种事不应该是那种只会纸上谈兵的老不死干的吗?)。
在Java8里和lambda相关的主要API就是Stream
了。在了解Stream的时候来顺便熟悉lambda吧。