Java 8謂詞鏈
1.概述
在本快速教程中,我們將討論在Java 8中鏈接Predicates
不同方法。
2.基本示例
首先,**讓我們看看如何使用簡單的Predicate
**來過濾名稱List
:
@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
過濾了名稱List
,以僅保留以“ A”開頭的名稱:
name -> name.startsWith("A")
但是,如果我們想應用多個Predicates
怎麼辦?
3.多個過濾器
如果我們要應用多個Predicates
,一種選擇是簡單地鏈接多個過濾器:
@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"));
}
現在,我們更新了示例,以通過提取以“ A”開頭且長度小於5的名稱來過濾列表。
我們使用了兩個過濾器-每個Predicate
。
4.複合Predicate
現在,我們可以使用具有復雜Predicate
一個過濾器,而不是使用多個過濾器:
@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"));
}
此選項比第一個選項更靈活,因為**我們可以使用按位運算來構建所需的Predicate
**使其盡可能複雜。
5.組合Predicates
接下來,如果我們不想使用按位運算來構建複雜的Predicate
,則Java 8 Predicate
具有有用的方法,可用於組合Predicates
。
我們將使用Predicate.and()
, Predicate.or()
和Predicate.negate().
方法組合Predicates
Predicate.negate().
5.1。 Predicate.and()
在此示例中,我們將明確定義Predicates
,然後使用Predicate.and():
將它們組合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"));
}
如我們所見,語法非常直觀,方法名稱建議操作的類型。使用and()
,我們通過僅提取同時滿足兩個條件的名稱來過濾List
。
5.2。 Predicate.or()
我們還可以使用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"));
}
5.3。 Predicate.negate()
當結合我們的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
。
5.4。內聯合併Predicates
我們不需要顯式定義Predicates
來使用and(),
or()
和negate().
我們還可以通過強制轉換Predicate
來內聯使用它們:
@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
集合
最後,讓我們看看如何通過減少Predicates
來鏈接Predicates
集合。
在下面的示例中,我們使用Predicate.and()
合併了一個Predicates
List
:
@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"));
}
7.結論
在本文中,我們通過使用filter(),
構建複雜的Predicates
以及組合Predicates.
,探索了Java 8中鏈接謂詞的不同方法Predicates.
完整的源代碼可在GitHub上獲得。