死磕Lambda表达式(六):Consumer、Predicate、Function复合

你的无畏来源于无知。——《三体》

在上一篇文章(传送门)中介绍了Comparator复合,这次我们来介绍一下其他的复合Lambda表达式。

Consumer复合

Consumer接口中,有一个默认方法andThen,它的入参还是Consumer接口的实例。做完上一个Consumer的操作以后,再做当前Consumer的操作,就像工厂的流水线一样,比如:

Consumer<Mask> brand = m -> m.setBrand("3M");
Consumer<Mask> type = m -> m.setType("N95");
Consumer<Mask> price = m -> m.setPrice(19.9);
Consumer<Mask> print = System.out::println;

brand.andThen(type)
        .andThen(price)
        .andThen(print)
        .accept(new Mask());

上面的代码分别声明了4个Consumer接口的实例,然后再把它们组装成一个流水线,先把口罩品牌赋值为3M,再把口罩类型赋值为N95,再把口罩价格赋值为19.9,最后把口罩实例打印出来,运行结果如下:

Mask{brand='3M', type='N95', price=19.9}

Predicate复合

Predicate接口一共有3个默认方法:negateandor,用它们可以创建更加复杂的Predicate接口实例。

negate方法

negate方法就是做非运算。比如,判断口罩类型是N95:

Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
System.out.println(isN95.test(mask));

运行结果为:

true

那么,使用negate方法以后,就变成了判断口罩类型不是N95:

Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
System.out.println(isN95.negate().test(mask));

运行结果为:

false

and方法

and方法就是做与运算。比如:

Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
Predicate<Mask> lessThan20 = m -> m.getPrice() < 20.0;
System.out.println(isN95.and(lessThan20).test(mask));

上面的代码分别声明了2个Predicate接口的实例,分别是判断口罩类型是N95判断口罩价格小于20,使用and方法以后,表示口罩类型是N95 并且 口罩价格小于20,运行结果如下:

true

or方法

or方法就是做或运算。比如:

Mask mask = new Mask("Honeywell", "N95", 21.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
Predicate<Mask> lessThan20 = m -> m.getPrice() < 20.0;
System.out.println(isN95.or(lessThan20).test(mask));

上面的代码分别声明了2个Predicate接口的实例,分别是判断口罩类型是N95判断口罩价格小于20,使用or方法以后,表示口罩类型是N95 或者 口罩价格小于20,运行结果如下:

true

and方法和or方法组合使用

当and方法和or方法组合使用时,优先级是由在Lambda表达式链中的位置决定的,从左到右优先级从高到低,比如:

Mask mask = new Mask("3M", "N95", 21.5);
Predicate<Mask> is3M = m -> "3M".equals(m.getType());
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
Predicate<Mask> lessThan20 = m -> m.getPrice() < 20.0;
System.out.println(is3M.or(isN95).and(lessThan20).test(mask));

上面的代码分别声明了3个Predicate接口的实例,分别是判断口罩品牌是3M判断口罩类型是N95判断口罩价格小于20,3个Predicate组合以后是is3M.or(isN95).and(lessThan20),根据从左到右优先级从高到低,组合以后的逻辑是(is3M || isN95 ) && lessThan20,所以运行结果如下:

false

Function复合

Function接口一共有2个默认方法,分别是:andThencompose,用它们可以创建更加复杂的Function接口实例。

andThen方法

Function接口的andThen方法,和Consumer接口的类似,它的入参还是Function接口的实例。做完上一个Function的操作以后,再做当前Function的操作,比如:

Function<Integer, Integer> plusTwo = x -> x + 2;
Function<Integer, Integer> timesThree = x -> x * 3;
System.out.println(plusTwo.andThen(timesThree).apply(1));
System.out.println(plusTwo.andThen(timesThree).apply(2));
System.out.println(plusTwo.andThen(timesThree).apply(3));

上面的代码分别声明了2个Function接口的实例,先加2,然后再乘以3,也就是(x + 2) * 3,运行结果如下:

9
12
15

compose方法

Function接口的compose方法,和andThen方法相反的,先做当前Function的操作,然后再做上一个Function的操作,比如:

Function<Integer, Integer> plusTwo = x -> x + 2;
Function<Integer, Integer> timesThree = x -> x * 3;
System.out.println(plusTwo.compose(timesThree).apply(1));
System.out.println(plusTwo.compose(timesThree).apply(2));
System.out.println(plusTwo.compose(timesThree).apply(3));

上面的代码分别声明了2个Function接口的实例,先乘以3,然后再加2,也就是(x * 3) + 2,运行结果如下:

5
8
11

《死磕Lambda表达式》目录

上一篇:Mozilla宣布年底前放弃支持Persona登录服务


下一篇:容器服务kubernetes federation v2实践四:基于External-DNS的多集群Service DNS实践