从什么是好代码讲起
最近又在看《clean code》,回顾了一下里面提到的整洁代码的标准。
然后审视了一下现在的项目代码,里面还有很多if,for循环。比如:
// 查询用户列表
List<User> userList = userService.list();
// 打印用户信息
for (int i = 0; i < userList.size(); i++) {
System.out.println(userList.get(i));
}
并不是这种写法不好(用《clean code》的话说就是,它不并是一个坏味道),非常多优秀的框架,类库也是这样写的。但现在项目用是jdk1.8啊,已经出来多久了!隔壁有的已经到17了,要求使用1.8的新特性不过分吧?
不仅是现在(也不仅是现在的公司),再把时间也往前推到17年(往前推服务过的2个公司),都存在一样的现象:jdk版本是1.8,而写代码的风格却还停留在1.4!而其中的原因也很简单甚至不值得一提:并不是lambda表达式不好,或者抗拒这种使用方法,就是不熟悉而已。
没有看错,就是有的程序员不熟悉而已,当他愿意花时间去熟悉lambda表达式,就很快应用并爱不释手。所以,我认为整洁代码还有一个评判因素就是,使用jdk新的代码风格编写代码!
重申函数式接口定义
3年前在JAVA8-lambda表达式1:什么是lambda表达式,一文里面认识了什么是lambda,这里再简单回顾一下:只有一个抽象方法的接口,就是函数式接口!
这里一再强调lambda表达式的定义,多数时候可以直接使用内置的函数来解决问题,比如JAVA8-lambda表达式2:常用的集合类api,甚至自定义函数JAVA8-lambda表达式6:重构和定制收集器
重要的函数接口
上面例子里面的代码,如果要改写成lambda表达式,可以如下:
userList.stream().forEach(user -> System.out.println(user));
而forEach方法里面的参数其实就是一个函数:Consumer函数式接口:
Consumer是一个比较重要的函数,表示接受一个参数用于执行代码且没有返回值。
Java中重要的函数接口
其中Java中重要的函数接口,有以下几个:
接口
|
参数
|
返回类型
|
示例
|
Predicate<T>
|
T
|
boolean
| 条件判断:接受一个参数并判断给定条件是否成立,比如过滤出age>60的用户 |
Consumer<T>
| T |
void
| 立即执行:接受一个参数并立即执行给定代码,比如例子中的打印用户信息 |
Function<T,R>
| T |
R
| 立即执行:接受一个参数立即执行给定代码并转换成指定的类型返回,比如将Predicate过滤出age>60的用户设置为老年客户 |
Supplier<T>
|
None
| T | 获取结果:立即执行给定代码并获取指定结果,比如收集上面的过滤结果 |
UnaryOperator<T>
| T | T | 立即执行:对单个操作数的操作,产生与其操作数相同类型的结果,比如要将userList转成Map集合就可以用到 |
BinaryOperator<T>
|
(T, T)
| T | 二元操作:接受2个相同类型参数立即执行给定代码,并返回相同类型的结果,比如统计所有用户的年龄之和 |