JDK8-1-Lambda表达式(2)-方法传递(行为参数化)
Java 8 允许程序将方法作为参数传递,先看一个例子:
苹果实体类:
public class Apple {//颜色private String color;//重量,单位克,150克到400克private double weight;public Apple(String color, double weight) {this.color = color;this.weight = weight;}//get set 方法省略。。。
}
以下,filterGreenApples ,filterHeavyApples 方法分别表示过滤出不同类型的苹果
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class AppleFilterTest {private static final List<Apple> apples = Arrays.asList(new Apple("red", 400), new Apple("green", 300),new Apple("yellow", 100), new Apple("green", 200));/*** 过滤出绿色的苹果* @param inventory* @return*/public static List<Apple> filterGreenApples(List<Apple> inventory) {List<Apple> result = new ArrayList<>();for (Apple apple : inventory) {if ("green".equals(apple.getColor())) {result.add(apple);}}return result;}/*** 过滤出重苹果* @param inventory* @return*/public static List<Apple> filterHeavyApples(List<Apple> inventory) {List<Apple> result = new ArrayList<>();for (Apple apple : inventory) {if (apple.getWeight() > 150) {result.add(apple);}}return result;}public static void main(String[] args) {List<Apple> greenApples = filterGreenApples(apples);System.out.println(greenApples);List<Apple> heavyApples = filterHeavyApples(apples);System.out.println(heavyApples);}}
从代码中可以看出,filterGreenApples 与 filterHeavyApples 方法代码几乎一模一样,仅仅只有 if 条件中的代码有区别,既然这样为什么不可以将筛选的代码抽出,过滤的部分作为公共逻辑呢
改造的部分为:
"green".equals(apple.getColor())
apple.getWeight() > 150
这两个条件都与 Apple apple 这个对象关联,可以将是否满足条件封装成一个接口,Apple apple 作为参数传入,接口定义如下:
为了更加通用,所以定义成泛型,不过实际工作中不用自己定义,因为JDK8已经有了,具体路径为:
java.util.function.Predicate
public interface Predicate<T> {boolean test(T t);
}
filterGreenApples,filterHeavyApples 可以统一用一个方法 filterApples 代替,只要将条件参数传入即可,filterApples 方法如下,其中 predicate 为条件,if 条件中只需调用 predicate test 方法,成功表示满足条件:
public static List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> predicate) {List<Apple> result = new ArrayList<>();for (Apple apple : inventory) {if (predicate.test(apple)) {result.add(apple);}}return result;
}
调用方式:
List<Apple> greenApples = filterApples(apples, apple -> "green".equals(apple.getColor()));
List<Apple> heavyApples = filterApples(apples, apple -> apple.getWeight() > 150);
实际工作使用
顺序处理(串行流)
在实际工作中我们根本不用定义 filterApples 这个方法,因为JDK已经提供 filter 方法,实际使用如下:
这里使用了JDK8的新特性 Stream API,Stream 支持顺序或并行处理,下例为顺序处理
List<Apple> greenApples = apples.stream().filter(apple -> "green".equals(apple.getColor())).collect(Collectors.toList());List<Apple> heavyApples = apples.stream().filter(apple -> apple.getWeight() > 150).collect(Collectors.toList());
filter 方法接收 java.util.function.Predicate 类型
Stream<T> filter(Predicate<? super T> predicate);
并行处理(并行流)
Java 8 parallelStream API 允许程序对数据操作做并行处理,即可以让CPU 某个内核处理数据列表的前一段,另外的内核处理数据列表的后一段,如下图所示:
图片来源:《Java 8 实战》
parallelStream API 具体使用方法如下:
List<Apple> greenApples2 = apples.parallelStream().filter(apple -> "green".equals(apple.getColor())).collect(Collectors.toList());