Java8 Predicate花樣用法詳解
1. 簡介
本文介紹Java 8 Predicate鏈.
2. 基本用法
怎么使用簡單的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")
那么如果多個條件這么辦?
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"));
}用兩個filter傳入兩個 Predicate分別過濾 【以A開頭的】和【姓名長度小于5】的。


4. 復雜條件
@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"));
}使用一個 filter 傳入復雜的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"));
}兩個條件都要滿足

5.2. Predicate.or()
滿足其中一個即可
@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;
相當于
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集合
在開始介紹之前,簡單介紹下 reduce 函數(shù):
`java.util.stream.Stream#reduce(T, java.util.function.BinaryOperator<T>)`
源碼的注釋中給出等價的寫法:
T result = identity;
for (T element : this stream)
result = accumulator.apply(result, element)
return result;即,第一個參數(shù)當做初始值,后續(xù)參數(shù)和第一個參數(shù)進行運算,最終得到結(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 操作,通常會將初始值設置為 false,因為如果初始值為 true 不管后續(xù)條件是否為 true 最終結(jié)果都為 true。
7. 結(jié)論
本文介紹Java 8 Predicate。介紹了 Predicate在Stream的filter函數(shù)中的運用。講述了復雜的Predicate或者Predicate的組合的用法。
英文原文:https://www.baeldung.com/java-predicate-chain
到此這篇關于Java 8 Predicate花樣用法詳解的文章就介紹到這了,更多相關Java 8 Predicate內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解
這篇文章主要介紹了 Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07
深入解析Java的Spring框架中的混合事務與bean的區(qū)分
這篇文章主要介紹了Java的Spring框架中的混合事務與bean的區(qū)分,Spring是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2016-01-01
Java 數(shù)據(jù)結(jié)構與算法系列精講之紅黑樹
紅黑樹的應用比較廣泛,主要是用它來存儲有序的數(shù)據(jù),它的時間復雜度是O(lgn),效率非常之高。例如,Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虛擬內(nèi)存的管理,都是通過紅黑樹去實現(xiàn)的2022-02-02
Java使用jni清屏功能的實現(xiàn)(只針對cmd)
JNI是Java Native Interface的縮寫,它提供了若干的API實現(xiàn)了Java和其他語言的通信(主要是C&C++)。這篇文章主要介紹了Java使用jni清屏功能的實現(xiàn)(只針對cmd) ,感興趣的朋友跟隨腳本之家小編一起學習吧2018-05-05
Java項目在Idea中開發(fā)遇到所有代碼爆紅的問題與解決辦法
今天打開項目時發(fā)現(xiàn)idea竟然爆紅,通過查找相關資料用于解決,下面這篇文章主要給大家介紹了關于Java項目在Idea中開發(fā)遇到所有代碼爆紅的問題與解決辦法的相關資料,需要的朋友可以參考下2023-06-06
Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別
這篇文章主要給大家介紹了關于Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Spring Boot具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-06-06
Java數(shù)據(jù)結(jié)構之KMP算法的實現(xiàn)
這篇文章主要為大家詳細介紹了Java數(shù)據(jù)結(jié)構中KMP算法的原理與實現(xiàn),文中的示例代碼講解詳細,對我們學習Java有一定的幫助,需要的可以參考一下2022-11-11

