你的无畏来源于无知。——《三体》
在上一篇文章(传送门)中介绍了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个默认方法:negate
、and
和or
,用它们可以创建更加复杂的Predicate接口实例。
negate方法
negate方法就是做非运算。比如,判断口罩类型是N95:
代码语言:javascript复制Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
System.out.println(isN95.test(mask));
运行结果为:
代码语言:javascript复制true
那么,使用negate方法以后,就变成了判断口罩类型不是N95:
代码语言:javascript复制Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
System.out.println(isN95.negate().test(mask));
运行结果为:
代码语言:javascript复制false
and方法
and方法就是做与运算。比如:
代码语言:javascript复制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方法就是做或运算。比如:
代码语言:javascript复制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表达式链中的位置决定的,从左到右优先级从高到低,比如:
代码语言:javascript复制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个默认方法:andThen
和compose
,用它们可以创建更加复杂的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表达式》系列
- 死磕Lambda表达式(一):初识Lambda
- 死磕Lambda表达式(二):Lambda的使用
- 死磕Lambda表达式(三):更简洁的Lambda
- 死磕Lambda表达式(四):常用的函数式接口
- 死磕Lambda表达式(五):Comparator复合