参考文档/内容:
本系列文章内容主要来自于《java8 实战》,加上了自己一些想法和重新编写的例子,主要目的是为了加深自己的印象,方便后期的复习。
所以有任何问题请购阅《java8 实战》内容,支持正版。
一、学习大纲
- 函数式编程
- Lambda 表达式
- Stream
- 并行数据处理与性能
- Optional
- CompletableFuture:组合式异步编程
- 新的日期和时间 API
二、思考和反思
在学习jdk8新特性之前,请先考虑一下jdk8之前最让你觉得不爽的地方:
- 模板代码
- 为什么不能把方法作为一个参数传递到另一个方法中?
- 无处不在的NullPointerException
- 垃圾的字符串拼接
可能每个人有不同的想法,但是这至少是我觉得不爽的几个点;废话少说,让我们“回味”一下这个痛苦的过程
2.1、模板代码
什么是模板代码?要理解这个概念先看一下代码:
new Thread(new Runnable() {
@Override
public void run() {
System.err.println("run......");
}
}).start();
这是我们日常创建一个线程所写的代码,在我看来上面有用的就只有一句 System.err.println(“run…”); 其它Runnable类中的代码都一样呀,都是模板,那为什么就不能省略呢?
2.2、方法作为参数传递
这里有这样一个需求:
有一堆的苹果,不同的品种(红富士、蛇果、金冠…),不同的颜色(青的、红的),不同的重量,第一次让你按照规则挑选出青色的苹果,第二次让你挑选出青色并且重量大于500g的苹果,第三次可能让你挑选出红富士中单个苹果重量再500g-800g 之间的苹果…
我们总结以下上面的操作:
public static List<Apple> filterApples(List<Apple> inventory){
List<Apple> result = new ArrayList<>();
for (Apple apple: inventory){
// 这里是不是可以通过外部将过滤的规则传过来,这样我们就不用的来回调整代码了
if ("green".equals(apple.getColor())) {
result.add(apple);
}
}
return result;
}
看了上面的代码,可以看出三次需求的绝大部分代码都是重复的,只不过每次的过滤条件不一样,那么就不能把过滤的条件(方法)作为参数传递过来,这样就不用的来回折腾代码了
2.3、NullPointerException
这个异常觉得是JAVA开发生涯遇到的最最最…常见的异常,特别要获取一个对象中对象中对象的属性时,那更让人绝望,不说了看代码:
public String getCarInsuranceName(Person person) {
return person.getCar().getInsurance().getName();
}
这个代码的目的我们只是为了获取:person对象中car属性对象中insurance属性对象的name 属性,假如说 其中 car或者 insurance 任意一个对象为空,那就会抛出 NullPointerException 异常。
为此我们不得不每次获取属性之后就要进行null 的判断,试想一下这个只是对象中的二级对象的属性,假如说要获取对象中10级对象的属性,那…
不说了我去工地搬砖了,转行搬砖也挺好的…
2.4、垃圾的字符串拼接
不细说直接看代码:
String sql = "select id, name \n "
+ " from user \n"
+ " where id=? \n"
+ " and deleteFlag = 0";
String json = "{\n"
+ "\"id\": 123,\n"
+ "\name\": \"Yanbin\"\n"
+ "}";
fxxk, 每次看到这样的代码我都一顿头疼,作为同在JVM上运行的Scala 或 Groovy 是用三个双引号 (""")来解决这种带格式的数据,甚至是JavaScript都引入了(``)来解决这个问题,可JAVA你就不考虑不考虑解决一下;
如果你和我有同样的想法,我这里告诉你一个不幸的消息:JDK8中这个问题依然存在,甚至JDK9、JDK10… 中这个问题依然存在;
有消息称:JDK13 引入了 文本块 有望解决这个问题,嗯…希望还是要有的
2.5、问题的解决
除了最后一个问题在 JDK8 中没有得到解决之外,其他的都有解决方案,甚至JDK8 给我们带来了更大的惊喜,那我们就抱着这些问题来进入到 JDK8 的世界中。