死磕Lambda表示式(六):Consumer、Predicate、Function複合
阿新 • • 發佈:2020-04-07
>你的無畏來源於無知。——《三體》
在上一篇文章([傳送門](https://mp.weixin.qq.com/s/AFu_fOFct5kgurIub8MCNw))中介紹了Comparator複合,這次我們來介紹一下其他的複合Lambda表示式。
### Consumer複合
`Consumer`介面中,有一個預設方法`andThen`,它的入參還是`Consumer`介面的例項。做完上一個`Consumer`的操作以後,再做當前`Consumer`的操作,就像工廠的流水線一樣,比如:
```java
Consumer brand = m -> m.setBrand("3M");
Consumer type = m -> m.setType("N95");
Consumer price = m -> m.setPrice(19.9);
Consumer 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}
```
歡迎關注微信公眾號:萬貓學社 ,每週一分享Java技術乾貨。
### Predicate複合
Predicate介面一共有3個預設方法:`negate`、`and`和`or`,用它們可以建立更加複雜的Predicate介面例項。
#### negate方法
negate方法就是做非運算。比如,判斷口罩型別是N95:
```java
Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate isN95 = m -> "N95".equals(m.getType());
System.out.println(isN95.test(mask));
```
執行結果為:
```
true
```
那麼,使用negate方法以後,就變成了判斷口罩型別不是N95:
```java
Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate isN95 = m -> "N95".equals(m.getType());
System.out.println(isN95.negate().test(mask));
```
執行結果為:
```
false
```
#### and方法
and方法就是做與運算。比如:
```java
Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate isN95 = m -> "N95".equals(m.getType());
Predicate lessThan20 = m -> m.getPrice() < 20.0;
System.out.println(isN95.and(lessThan20).test(mask));
```
上面的程式碼分別聲明瞭2個`Predicate`介面的例項,分別是**判斷口罩型別是N95**和**判斷口罩價格小於20**,使用`and`方法以後,表示口罩型別是N95 **並且** 口罩價格小於20,執行結果如下:
```
true
```
#### or方法
or方法就是做或運算。比如:
```java
Mask mask = new Mask("Honeywell", "N95", 21.5);
Predicate isN95 = m -> "N95".equals(m.getType());
Predicate 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表示式鏈中的位置決定的,從左到右優先順序從高到低,比如:
```java
Mask mask = new Mask("3M", "N95", 21.5);
Predicate is3M = m -> "3M".equals(m.getType());
Predicate isN95 = m -> "N95".equals(m.getType());
Predicate 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
```
歡迎關注微信公眾號:萬貓學社 ,每週一分享Java技術乾貨。
### Function複合
Function介面一共有2個預設方法:`andThen`和`compose`,用它們可以建立更加複雜的Function介面例項。
#### andThen方法
`Function`介面的`andThen`方法,和`Consumer`介面的類似,它的入參還是`Function`介面的例項。做完上一個`Function`的操作以後,再做當前`Function`的操作,比如:
```java
Function plusTwo = x -> x + 2;
Function 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`的操作,比如:
```java
Function plusTwo = x -> x + 2;
Function 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](https://mp.weixin.qq.com/s/ce85WnptSOyQaMBep8L_oA)
- [死磕Lambda表示式(二):Lambda的使用](https://mp.weixin.qq.com/s/wW1IWOIxKR_LU0Rf-TaxtA)
- [死磕Lambda表示式(三):更簡潔的Lambda](https://mp.weixin.qq.com/s/wVlVabABtiLmhmf8WNbyHQ)
- [死磕Lambda表示式(四):常用的函式式介面](https://mp.weixin.qq.com/s/5u2P9QFJJ1wR-yT46ysuig)
- [死磕Lambda表示式(五):Comparator複合](https://mp.weixin.qq.com/s/AFu_fOFct5kgurIub8MCNw)
- [死磕Lambda表示式(六):Consumer、Predicate、Function複合](https://mp.weixin.qq.com/s/CGO59kUQxrngOjthI_3OCQ)
微信公眾號:萬貓學社
微信掃描二維碼
獲得更多Java技術乾貨