这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战
阅读《Java实战》一书,系统学习梳理下Java8之后新增的特性,lambda表达式、方法引用、流、默认方法、Optional、CompletableFuture等等,本文为前两章的总结。
1、基础概念
1.1 流处理
- Java8提供的Stream API,支持多个数据处理的并行操作,思路是从高层角度描述需求,而由“实现”(Stream库)来选择底层最佳执行机制。
- 将集合的制造和处理构成抽象封装,如循环迭代直接由库内部进行,使用时不用纠结循环流程。
- 提供封装的并行处理能力,基于分治+无共享可变状态。
1.2 方法引用&Lambda-匿名函数
-
方法引用:类比对象引用,将方法作为一等值(执行时可做参数)来传递。
-
Lambda:将函数作为一等值来传递。
1.3 接口的默认方法
让接口支持声明默认的接口方法实现,只有类中没有实现具有默认方法的接口,才会去调用接口中的默认方法。
1.4 Java模块化
- 解决问题:
- 基于jar的java包没有声明的结构,不适合组件化构建。
- 迭代演进中,一个接口的改变,实现该接口的所有类多要改变
- 处理方式:
- java9支持通过语法定义由一系列包组合成的模块,更好控制命名空间和包可见性。
- 引入接口默认方法,支持接口持续演进,而不影响实现该接口的所有类。
1.5 其他内容
- Optional处理null问题
- 模式匹配
2、行为参数化演进
定义:
一个方法可以接收多个不同的行为作为参数,并在内部使用他们,完成不同的行为能力。
演进场景:
根据苹果的颜色或者重量属性遍历过滤出来苹果。
版本1:传统实现
// 版本1: 直接迭代筛选
public static List<Apple> filterApples(List<Apple> inventory,Color color){
List<Apple> filterApples = new ArrayList<>();
for(Apple apple:inventory){
if(color.equals(apple.getColor())){
filterApples.add(apple);
}
}
return filterApples;
}
版本2:基于行为接口+具体实现类,实现行为参数化
// 版本2:基于接口+实现类的策略模式,用对象封装方法策略
public static List<Apple> filterApples(List<Apple> inventory,ApplePredicate predicate){
List<Apple> filterApples = new ArrayList<>();
for(Apple apple:inventory){
if(predicate.test(apple)){
filterApples.add(apple);
}
}
return filterApples;
}
// 行为接口
interface ApplePredicate {
public boolean test(Apple a);
}
// 行为参数化对象:红色苹果判断
class AppleRedPredicate implements ApplePredicate{
@Override
public boolean test(Apple a) {
return Color.RED.equals(a.getColor());
}
}
// 行为参数化对象:红色苹果判断
class AppleHeavyWeightPredicate implements ApplePredicate{
@Override
public boolean test(Apple a) {
return a.getWeight()>150;
}
}
版本3:基于匿名类,简化类数量
// 版本3:基于匿名类
List<Apple> redApples3 = filterApples(inventory, new ApplePredicate() {
@Override
public boolean test(Apple a) {
return Color.RED.equals(a.getColor());
}
});
版本4:用lambda替换匿名类
// 版本4:用lambda简化匿名类
List<Apple> result = filterApples(inventory,(Apple a) -> Color.RED.equals(a.getColor()));
版本5:将List类型抽象化(将过滤行为复用)
// 版本5:类型抽象化(引入类型参数)
interface Predicate<T>{
boolean test(T t);
}
// 泛化的过滤函数
static <T> List<T> filter(List<T> list,Predicate<T> p){
List<T> result = new ArrayList<T>();
for(T e:list){
if(p.test(e)){
result.add(e);
}
}
return result;
}
// 使用示例
List<Apple> result2 = filter(inventory,(Apple a) -> a.getWeight()>500);
System.out.println(result2);
// 过滤偶数
Integer[] arrInt = {1,2,3,4,5,6};
System.out.println(filter(Arrays.asList(arrInt),(Integer i) -> i%2==0));
总结:
- 核心:一个方法接受多个不同行为作为参数,并在内部使用它,完成不同能力。
- 目的场景:适应不断变化的要求,不同行为参数化,减少硬编码,适合条件多变的排序&过滤的规则、线程等。
- java8之前用匿名类来处理创建大量类实现问题,java8之后基于lambda实现