Java 8 Predicate Chain

1. Oversigt

I denne hurtige vejledning vi diskuterer forskellige måder at kæde på Predikater i Java 8.

2. Grundlæggende eksempel

Først, lad os se, hvordan man bruger en simpel Prædikat at filtrere en Liste af navne:

@Test offentlig ugyldig nårFilterList_thenSuccess () {List names = Arrays.asList ("Adam", "Alexander", "John", "Tom"); Listeresultat = names.stream () .filter (name -> name.startsWith ("A")) .collect (Collectors.toList ()); assertEquals (2, result.size ()); assertThat (resultat, indeholder ("Adam", "Alexander")); }

I dette eksempel filtrerede vi vores Liste af navne for kun at efterlade navne, der starter med "A" ved hjælp af Prædikat:

name -> name.startsWith ("A")

Men hvad hvis vi ville anvende flere Predikater?

3. Flere filtre

Hvis vi ville anvende flere Predikater, en mulighed er simpelthen at kæde flere filtre:

@Test offentlig ugyldig nårFilterListWithMultipleFilters_thenSuccess () {List result = names.stream () .filter (name -> name.startsWith ("A")). Filter (name -> name.length () <5) .collect (Collectors. toList ()); assertEquals (1, result.size ()); assertThat (resultat, indeholder ("Adam")); }

Vi har nu opdateret vores eksempel for at filtrere vores liste ved at udtrække navne, der starter med "A" og har en længde, der er mindre end 5.

Vi brugte to filtre - et til hver Prædikat.

4. Kompleks Prædikat

Nu, i stedet for at bruge flere filtre, vi kan bruge et filter med et kompleks Prædikat:

@Test offentlig ugyldig nårFilterListWithComplexPredicate_thenSuccess () {List result = names.stream () .filter (name -> name.startsWith ("A") && name.length () <5) .collect (Collectors.toList ()); assertEquals (1, result.size ()); assertThat (resultat, indeholder ("Adam")); }

Denne mulighed er mere fleksibel end den første, som vi kan bruge bitvise operationer til at opbygge Prædikatså kompliceret som vi ønsker.

5. Kombination Predikater

Dernæst, hvis vi ikke vil bygge et kompleks Prædikat ved hjælp af bitvise operationer, Java 8 Prædikat har nyttige metoder, som vi kan bruge til at kombinere Predikater.

Vi kombinerer Predikater ved hjælp af metoderne Predicate.and (), Predicate.or ()og Predicate.negate ().

5.1. Predicate.and ()

I dette eksempel definerer vi vores Predikater eksplicit, og så kombinerer vi dem ved hjælp af Predicate.and ():

@Test offentlig ugyldig nårFilterListWithCombinedPredicatesUsingAnd_thenSuccess () {Predicate predicate1 = str -> str.startsWith ("A"); Predikat predikat2 = str -> str.længde () <5; Listeresultat = names.stream () .filter (predicate1.and (predicate2)) .collect (Collectors.toList ()); assertEquals (1, result.size ()); assertThat (resultat, indeholder ("Adam")); }

Som vi kan se, er syntaksen ret intuitiv, og metodens navne antyder typen af ​​operation. Ved brug af og(), vi har filtreret vores Liste ved kun at udtrække navne, der opfylder begge betingelser.

5.2. Predicate.or ()

Vi kan også bruge Predicate.or () at kombinere Predikater.

Lad os udtrække navne, der starter med "J" samt navne med en længde, der er mindre end 4:

@Test offentlig ugyldig nårFilterListWithCombinedPredicatesUsingOr_thenSuccess () {Predicate predicate1 = str -> str.startsWith ("J"); Predikat predikat2 = str -> str.længde () <4; Listeresultat = names.stream () .filter (predicate1.or (predicate2)) .collect (Collectors.toList ()); assertEquals (2, result.size ()); assertThat (resultat, indeholder ("John", "Tom")); }

5.3. Predikere.negate ()

Vi kan bruge Predikere.negate () når man kombinerer vores Predikater såvel:

@Test offentlig ugyldig nårFilterListWithCombinedPredicatesUsingOrAndNegate_thenSuccess () {Predicate predicate1 = str -> str.startsWith ("J"); Forudsig predikat2 = str -> str.længde () <4; Listeresultat = names.stream () .filter (predicate1.or (predicate2.negate ())) .collect (Collectors.toList ()); assertEquals (3, result.size ()); assertThat (resultatet indeholder ("Adam", "Alexander", "John")); }

Her har vi brugt en kombination af eller() og negere () for at filtrere Liste ved navne, der starter med “J” eller har en længde, der ikke er mindre end 4.

5.4. Forene Predikater Inline

Vi behøver ikke eksplicit at definere vores Predikater at bruge og(),eller()og neger ().

Vi kan også bruge dem inline ved at støbe Prædikat:

@Test offentlig ugyldig nårFilterListWithCombinedPredicatesInline_thenSuccess () {List result = names.stream () .filter (((Predicate) name -> name.startsWith ("A")). And (name -> name.length () <5)) .collect (Collectors.toList ()); assertEquals (1, result.size ()); assertThat (resultat, indeholder ("Adam")); }

6. Kombination af en samling af Predikater

Langt om længe, lad os se, hvordan man kæder en samling af Predikater ved at reducere dem.

I det følgende eksempel har vi en Liste af Predikater som vi kombinerede ved hjælp af Predicate.and ():

@Test offentlig ugyldig nårFilterListWithCollectionOfPredicatesUsingAnd_thenSuccess () {List allPredicates = ny ArrayList(); allPredicates.add (str -> str.startsWith ("A")); allPredicates.add (str -> str.contains ("d")); allPredicates.add (str -> str.length ()> 4); Listeresultat = names.stream () .filter (allPredicates.stream (). Reducer (x-> true, Predicate :: og)) .collect (Collectors.toList ()); assertEquals (1, result.size ()); assertThat (resultat, indeholder ("Alexander")); }

Bemærk, at vi bruger vores basisidentitet som:

x-> sandt

Men det vil være anderledes, hvis vi vil kombinere dem ved hjælp af Predicate.or ():

@Test offentlig ugyldig nårFilterListWithCollectionOfPredicatesUsingOr_thenSuccess () {List result = names.stream () .filter (allPredicates.stream (). Reduce (x-> false, Predicate :: or)) .collect (Collectors.toList ()); assertEquals (2, result.size ()); assertThat (resultat, indeholder ("Adam", "Alexander")); }

7. Konklusion

I denne artikel undersøgte vi forskellige måder at kæde Predicates i Java 8 ved hjælp af filter(), bygningskompleks Predikaterog kombinere Predikater.

Den fulde kildekode er tilgængelig på GitHub.