Java8 Predicate花樣用法詳解
1. 簡(jiǎn)介
本文介紹Java 8 Predicate鏈.
2. 基本用法
怎么使用簡(jiǎn)單的Predicate來過濾list中的name
@Test
public void whenFilterList_thenSuccess(){
List<String> names = Arrays.asList("Adam", "Alexander", "John", "Tom");
List<String> result = names.stream()
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());
assertEquals(2, result.size());
assertThat(result, contains("Adam","Alexander"));
}我們使用Predicate來篩選以大寫字母A開頭的姓名。
name -> name.startsWith("A")
那么如果多個(gè)條件這么辦?
3. 多條件過濾
@Test
public void whenFilterListWithMultipleFilters_thenSuccess(){
List<String> result = names.stream()
.filter(name -> name.startsWith("A"))
.filter(name -> name.length() < 5)
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Adam"));
}用兩個(gè)filter傳入兩個(gè) Predicate分別過濾 【以A開頭的】和【姓名長(zhǎng)度小于5】的。


4. 復(fù)雜條件
@Test
public void whenFilterListWithComplexPredicate_thenSuccess(){
List<String> result = names.stream()
.filter(name -> name.startsWith("A") && name.length() < 5)
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Adam"));
}使用一個(gè) filter 傳入復(fù)雜的Predicate.

5. 組合使用Predicate
Predicates可以將 Predicate.and(), Predicate.or() 和 Predicate.negate()組合起來使用。
5.1. Predicate.and()
@Test
public void whenFilterListWithCombinedPredicatesUsingAnd_thenSuccess(){
Predicate<String> predicate1 = str -> str.startsWith("A");
Predicate<String> predicate2 = str -> str.length() < 5;
List<String> result = names.stream()
.filter(predicate1.and(predicate2))
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Adam"));
}兩個(gè)條件都要滿足

5.2. Predicate.or()
滿足其中一個(gè)即可
@Test
public void whenFilterListWithCombinedPredicatesUsingOr_thenSuccess(){
Predicate<String> predicate1 = str -> str.startsWith("J");
Predicate<String> predicate2 = str -> str.length() < 4;
List<String> result = names.stream()
.filter(predicate1.or(predicate2))
.collect(Collectors.toList());
assertEquals(2, result.size());
assertThat(result, contains("John","Tom"));
}
5.3. Predicate.negate()
將此條件取反
Predicate<String> predicate2 = str -> str.length() < 4;
相當(dāng)于
Predicate<String> predicate2 = str -> str.length() >= 4;
@Test
public void whenFilterListWithCombinedPredicatesUsingOrAndNegate_thenSuccess(){
Predicate<String> predicate1 = str -> str.startsWith("J");
Predicate<String> predicate2 = str -> str.length() < 4;
List<String> result = names.stream()
.filter(predicate1.or(predicate2.negate()))
.collect(Collectors.toList());
assertEquals(3, result.size());
assertThat(result, contains("Adam","Alexander","John"));
}
5.4. 內(nèi)聯(lián)的方式組合使用Predicates
@Test
public void whenFilterListWithCombinedPredicatesInline_thenSuccess(){
List<String> result = names.stream()
.filter(((Predicate<String>)name -> name.startsWith("A"))
.and(name -> name.length()<5))
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Adam"));
}6. 組合Predicates集合
在開始介紹之前,簡(jiǎn)單介紹下 reduce 函數(shù):
`java.util.stream.Stream#reduce(T, java.util.function.BinaryOperator<T>)`
源碼的注釋中給出等價(jià)的寫法:
T result = identity;
for (T element : this stream)
result = accumulator.apply(result, element)
return result;即,第一個(gè)參數(shù)當(dāng)做初始值,后續(xù)參數(shù)和第一個(gè)參數(shù)進(jìn)行運(yùn)算,最終得到結(jié)果。
接下來我們看下面 reduce 中 and 操作的例子:
@Test
public void whenFilterListWithCollectionOfPredicatesUsingAnd_thenSuccess(){
List<Predicate<String>> allPredicates = new ArrayList<Predicate<String>>();
allPredicates.add(str -> str.startsWith("A"));
allPredicates.add(str -> str.contains("d"));
allPredicates.add(str -> str.length() > 4);
List<String> result = names.stream()
.filter(allPredicates.stream().reduce(x->true, Predicate::and))
.collect(Collectors.toList());
assertEquals(1, result.size());
assertThat(result, contains("Alexander"));
}注意這里初始條件是 true (如果初始條件為 false ,后續(xù)即使都滿足,和初始值一起 and ,也沒結(jié)果)

然后看 reduce 中使用 or 操作的例子:
@Test
public void whenFilterListWithCollectionOfPredicatesUsingOr_thenSuccess(){
List<String> result = names.stream()
.filter(allPredicates.stream().reduce(x->false, Predicate::or))
.collect(Collectors.toList());
assertEquals(2, result.size());
assertThat(result, contains("Adam","Alexander"));
}
Predicate::or 操作,通常會(huì)將初始值設(shè)置為 false,因?yàn)槿绻跏贾禐?true 不管后續(xù)條件是否為 true 最終結(jié)果都為 true。
7. 結(jié)論
本文介紹Java 8 Predicate。介紹了 Predicate在Stream的filter函數(shù)中的運(yùn)用。講述了復(fù)雜的Predicate或者Predicate的組合的用法。
英文原文:https://www.baeldung.com/java-predicate-chain
到此這篇關(guān)于Java 8 Predicate花樣用法詳解的文章就介紹到這了,更多相關(guān)Java 8 Predicate內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring AOP里的靜態(tài)代理和動(dòng)態(tài)代理用法詳解
這篇文章主要介紹了 Spring AOP里的靜態(tài)代理和動(dòng)態(tài)代理用法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
深入解析Java的Spring框架中的混合事務(wù)與bean的區(qū)分
這篇文章主要介紹了Java的Spring框架中的混合事務(wù)與bean的區(qū)分,Spring是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2016-01-01
Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之紅黑樹
紅黑樹的應(yīng)用比較廣泛,主要是用它來存儲(chǔ)有序的數(shù)據(jù),它的時(shí)間復(fù)雜度是O(lgn),效率非常之高。例如,Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虛擬內(nèi)存的管理,都是通過紅黑樹去實(shí)現(xiàn)的2022-02-02
SpringBoot自定義定時(shí)任務(wù)的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot自定義定時(shí)任務(wù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05
基于Java編寫第一個(gè)區(qū)塊鏈項(xiàng)目
區(qū)塊鏈?zhǔn)欠植际綌?shù)據(jù)存儲(chǔ)、點(diǎn)對(duì)點(diǎn)傳輸、共識(shí)機(jī)制、加密算法等計(jì)算機(jī)技術(shù)的新型應(yīng)用模式,下面這篇文章主要給大家介紹了基于Java實(shí)現(xiàn)區(qū)塊鏈的相關(guān)資料,需要的朋友可以參考下2021-08-08
Java使用jni清屏功能的實(shí)現(xiàn)(只針對(duì)cmd)
JNI是Java Native Interface的縮寫,它提供了若干的API實(shí)現(xiàn)了Java和其他語(yǔ)言的通信(主要是C&C++)。這篇文章主要介紹了Java使用jni清屏功能的實(shí)現(xiàn)(只針對(duì)cmd) ,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05
Java項(xiàng)目在Idea中開發(fā)遇到所有代碼爆紅的問題與解決辦法
今天打開項(xiàng)目時(shí)發(fā)現(xiàn)idea竟然爆紅,通過查找相關(guān)資料用于解決,下面這篇文章主要給大家介紹了關(guān)于Java項(xiàng)目在Idea中開發(fā)遇到所有代碼爆紅的問題與解決辦法的相關(guān)資料,需要的朋友可以參考下2023-06-06
Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別
這篇文章主要給大家介紹了關(guān)于Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
Java數(shù)據(jù)結(jié)構(gòu)之KMP算法的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Java數(shù)據(jù)結(jié)構(gòu)中KMP算法的原理與實(shí)現(xiàn),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下2022-11-11

