JDK8-1-Lambda表达式(2)-方法传递(行为参数化)

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());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值