系统学习Java新特性-行为参数化

这是我参与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
2
3
4
5
6
7
8
9
10
java复制代码    // 版本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:基于行为接口+具体实现类,实现行为参数化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
java复制代码    // 版本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:基于匿名类,简化类数量
1
2
3
4
5
6
7
java复制代码// 版本3:基于匿名类
List<Apple> redApples3 = filterApples(inventory, new ApplePredicate() {
@Override
public boolean test(Apple a) {
return Color.RED.equals(a.getColor());
}
});
版本4:用lambda替换匿名类
1
2
java复制代码// 版本4:用lambda简化匿名类
List<Apple> result = filterApples(inventory,(Apple a) -> Color.RED.equals(a.getColor()));
版本5:将List类型抽象化(将过滤行为复用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
java复制代码    // 版本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实现

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%