Java8 Predicate花樣用法詳解
1. 簡(jiǎn)介
本文介紹Java 8 Predicate鏈.
2. 基本用法
怎么使用簡(jiǎn)單的Predicate來(lái)過(guò)濾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來(lái)篩選以大寫(xiě)字母A開(kāi)頭的姓名。
name -> name.startsWith("A")
那么如果多個(gè)條件這么辦?
3. 多條件過(guò)濾
@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分別過(guò)濾 【以A開(kāi)頭的】和【姓名長(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()組合起來(lái)使用。
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è)條件都要滿(mǎn)足
5.2. Predicate.or()
滿(mǎn)足其中一個(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集合
在開(kāi)始介紹之前,簡(jiǎn)單介紹下 reduce 函數(shù):
`java.util.stream.Stream#reduce(T, java.util.function.BinaryOperator<T>)`
源碼的注釋中給出等價(jià)的寫(xiě)法:
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é)果。
接下來(lái)我們看下面 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ù)即使都滿(mǎn)足,和初始值一起 and ,也沒(méi)結(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 Boot下如何自定義Repository中的DAO方法
這篇文章主要介紹了Spring Boot下如何自定義Repository中的DAO方法,需要的朋友可以參考下2017-06-06Java編程關(guān)于子類(lèi)重寫(xiě)父類(lèi)方法問(wèn)題的理解
這篇文章主要介紹了Java編程關(guān)于子類(lèi)重寫(xiě)父類(lèi)方法問(wèn)題的理解,分享了有關(guān)子類(lèi)重寫(xiě)父類(lèi)的實(shí)例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11SpringBoot Tomcat啟動(dòng)實(shí)例代碼詳解
這篇文章主要介紹了SpringBoot Tomcat啟動(dòng)實(shí)例代碼詳解,需要的朋友可以參考下2017-09-09SpringBoot項(xiàng)目集成Flyway進(jìn)行數(shù)據(jù)庫(kù)版本控制的詳細(xì)教程
這篇文章主要介紹了SpringBoot項(xiàng)目集成Flyway進(jìn)行數(shù)據(jù)庫(kù)版本控制,本文分步驟通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07Java中常用的數(shù)據(jù)庫(kù)連接池_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
數(shù)據(jù)庫(kù)連接池負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫(kù)連接,它允許應(yīng)用程序重復(fù)使用一個(gè)現(xiàn)有的數(shù)據(jù)庫(kù)連接,而不是再重新建立一個(gè);釋放空閑時(shí)間超過(guò)最大空閑時(shí)間的數(shù)據(jù)庫(kù)連接來(lái)避免因?yàn)闆](méi)有釋放數(shù)據(jù)庫(kù)連接而引起的數(shù)據(jù)庫(kù)連接遺漏2017-08-08