Java 8謂詞鏈
在本快速教程中,我們將討論在Java 8中謂詞鏈Predicates的不同方法。
讓我們看看如何使用簡單的謂詞來過濾名稱列表:
@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")); } |
在這個例子中,我們過濾了名稱列表,只使用謂詞保留以“A”開頭的名稱 :
name -> name.startsWith("A")
但是,如果我們想要應用多個謂詞呢?
多個過濾器
如果我們想要應用多個謂詞,一個選項是簡單地連結多個過濾器:
@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")); } |
複雜的謂詞
我們可以使用一個帶有複雜謂詞的過濾器,而不是使用多個過濾器:
@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")); } |
這個選項比第一個選項更靈活,因為我們可以使用按位運算來構建我們想要的複雜謂詞。
.結合 謂詞
如果我們不想使用按位運算構建複雜的謂詞,Java 8 Predicate可以使用有用的方法來組合謂詞。
我們將使用Predicate.and(),Predicate.or()和Predicate.negate()方法組合謂詞。
我們將明確定義我們的謂詞,然後我們將使用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")); } |
我們可以看到,語法非常直觀,方法名稱表明了操作的型別,
我們也可以使用 Predicate.or()來組合Predicates。
讓我們提取名稱以“J”開頭,以及長度小於4的名稱:
@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")); } |
在組合我們的Predicates時我們也可以使用Predicate.negate():
@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")); } |
在這裡,我們使用or()和negate()的組合來按名稱以“J”開頭或長度不小於4 來過濾List。
結合謂詞內聯
我們不需要明確定義 Predicates要使用and(), or(), 和negate().
可以透過強制Cast謂詞來內聯它們 :
@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")); } |
結合一組謂詞
最後,讓我們看看如何透過Reducing合併它們來連結一組Predicates。
在下面的例子中,我們有一個列表的謂詞,我們使用組合Predicate.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")); } |
請注意:x->true 標識
如果我們想要使用Predicate.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")); } |
完整的原始碼可以在GitHub上獲得
相關文章
- java8-謂詞(predicate)Java
- C++謂詞C++
- 小解謂詞 access 與 filterFilter
- 原子謂詞公式和合式公式公式
- Partition 表掃描的過程,使用key作為謂詞與使用非key值做謂詞....
- 傳說中的“謂詞越界“場景
- SQL 改寫系列七:謂詞移動SQL
- SQL 改寫系列六:謂詞推導SQL
- 謂詞條件是is null走索引嗎?Null索引
- 【SQL】Oracle查詢轉換之謂詞推送SQLOracle
- C#2.0謂詞的簡單應用C#
- 優化擁有謂詞or的子查詢優化
- Oracle查詢轉換(四)連線謂詞推入Oracle
- 【GreatSQL最佳化器-02】索引和Sargable謂詞SQL索引
- CodeQL學習筆記(1)-QL語法(邏輯連線詞、量詞、聚合詞、謂詞和類)筆記
- 恕我直言你可能真的不會java第3篇:Stream的Filter與謂詞邏輯JavaFilter
- Oracle 12CR2查詢轉換之謂詞推送Oracle
- C++ 一元謂詞對應的lambda表示式C++
- 標準變成使謂詞(布林函式)返回true函式
- 大資料SQL中的Join謂詞下推,真的那麼難懂?大資料SQL
- 第二十一篇:最佳謂詞函式 --- 函式物件函式物件
- 基於CBO優化器謂詞選擇率的計算方法優化
- 執行計劃-4:謂詞的選擇時機與使用細節
- 【大資料】SparkSql連線查詢中的謂詞下推處理(一)大資料SparkSQL
- 【大資料】SparkSql 連線查詢中的謂詞下推處理 (二)大資料SparkSQL
- 謂詞下推:計算和儲存分開進行分析是低效的?
- 【TUNE_ORACLE】列出SQL謂詞中需要建立索引的列SQL參考OracleSQL索引
- 基於CBO最佳化器謂詞選擇率的計算方法
- 使用謂詞(NSPredicate)來提高集合遍歷與過濾查詢的效率
- [20150610]sql的謂詞中使用函式.txtSQL函式
- 人工智慧知識的表示——一節謂詞邏輯&產生式&框架人工智慧框架
- oracle 謂詞表示式對基數的影響(及11G改進)Oracle
- 資料庫鏈與同義詞資料庫
- CBO的查詢轉換(謂詞推入與子查詢展開(Subquery Unnesting))
- 一次ORACLE SQL謂詞跨界導致的執行計劃不準OracleSQL
- Java敏感詞過濾Java
- 所謂BAPIAPI
- 關於java提供的所謂的安全機制jaasJava