Filtrering og omdannelse af samlinger i Guava

1. Oversigt

I denne vejledning illustrerer vi, hvordan du gør det filtrer og transformer samlinger med Guava.

Vi filtrerer ved hjælp af Predicates, transformerer ved hjælp af de funktioner, som biblioteket giver, og til sidst ser vi, hvordan vi kombinerer både filtrering og transformation.

2. Filtrer en samling

Lad os starte med et simpelt eksempel på filtrering af en samling. Vi bruger en ud af boksen Predikat, der leveres af biblioteket og konstrueres via Predikater utility klasse:

@Test offentlig ugyldigt nårFilterWithIterables_thenFiltered () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Iterabelt resultat = Iterables.filter (navne, Predicates.containsPattern ("a")); assertThat (resultat, indeholderInAnyOrder ("Jane", "Adam")); }

Som du kan se, filtrerer vi Liste af navne for kun at få de navne, der indeholder tegnet “a” - og vi bruger Iterables.filter () at gøre det.

Alternativt kan vi gøre god brug af Collections2.filter () API også:

@Test offentlig ugyldig nårFilterWithCollections2_thenFiltered () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.filter (navne, Predicates.containsPattern ("a")); assertEquals (2, result.size ()); assertThat (resultat, indeholderInAnyOrder ("Jane", "Adam")); result.add ("anna"); assertEquals (5, names.size ()); }

Et par ting at bemærke her - først output af Collections.filter () er en levende visning af den originale samling - ændringer til den ene afspejles i den anden.

Det er også vigtigt at forstå det nu, resultatet er begrænset af prædikatet - hvis vi tilføjer et element, der ikke tilfredsstiller det Prædikat, en IllegalArgumentException vil blive kastet:

@Test (forventet = IllegalArgumentException.class) offentlig ugyldighed givenFilteredCollection_whenAddingInvalidElement_thenException () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.filter (navne, Predicates.containsPattern ("a")); result.add ("elvis"); }

3. Skriv brugerdefineret filter Prædikat

Næste - lad os skrive vores egne Prædikat i stedet for at bruge en fra biblioteket. I det følgende eksempel - definerer vi et predikat, der kun får de navne, der starter med "A" eller "J":

@Test offentligt ugyldigt nårFilterCollectionWithCustomPredicate_thenFiltered () {Predicate predicate = new Predicate () {@Override public boolean apply (String input) return input.startsWith ("A")}; Liste navne = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.filter (navne, predikat); assertEquals (3, result.size ()); assertThat (resultat, indeholderInAnyOrder ("John", "Jane", "Adam")); }

4. Kombiner flere prædikater

Vi kan kombinere flere prædikater ved hjælp af Predicates.or () og Predicates.and ().

I det følgende eksempel filtrerer vi a Liste af navne for at få de navne, der starter med “J” eller ikke indeholder “a”:

@Test offentlig ugyldig nårFilterUsingMultiplePredicates_thenFiltered () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.filter (navne, Predicates.or (Predicates.containsPattern ("J"), Predicates.not (Predicates.containsPattern ("a")))); assertEquals (3, result.size ()); assertThat (resultat, indeholderInAnyOrder ("John", "Jane", "Tom")); }

5. Fjern nulværdier under filtrering af en samling

Vi kan rydde op i nul værdier fra en samling ved at filtrere den med Predicates.notNull () som i følgende eksempel:

@Test offentlig ugyldig nårRemoveNullFromCollection_thenRemoved () {List names = Lists.newArrayList ("John", null, "Jane", null, "Adam", "Tom"); Samlingsresultat = Collections2.filter (navne, Predicates.notNull ()); assertEquals (4, result.size ()); assertThat (resultat, indeholderInAnyOrder ("John", "Jane", "Adam", "Tom")); }

6. Kontroller, om alle elementer i en samling matcher en betingelse

Lad os derefter kontrollere, om alle elementer i en samling matcher en bestemt tilstand. Vi bruger Iterables.all () for at kontrollere, om alle navne indeholder “n” eller “m”, skal vi kontrollere, om alle elementer indeholder “a”:

@Test offentligt ugyldigt nårCheckingIfAllElementsMatchACondition_thenCorrect () m ")); assertTrue (result); result = Iterables.all (names, Predicates.containsPattern (" a ")); assertFalse (result); 

7. Transformer en samling

Lad os nu se, hvordan man gør det omdanne en samling ved hjælp af en Guava Fungere. I det følgende eksempel transformerer vi a Liste af navne til en Liste af Heltal (navnets længde) med Iterables.transform ():

@Test public void whenTransformWithIterables_thenTransformed () {Function function = new Function () {@Override public Integer apply (String input) {return input.length (); }}; Liste navne = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Iterabelt resultat = Iterables.transform (navne, funktion); assertThat (resultat, indeholder (4, 4, 4, 3)); }

Vi kan også bruge Collections2.transform () API som i følgende eksempel:

@Test offentligt ugyldigt nårTransformWithCollections2_thenTransformed () {Funktion func = ny funktion () {@ Override offentlig heltal gælder (String input) {return input.length (); }}; Liste navne = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.transform (navne, func); assertEquals (4, result.size ()); assertThat (resultat, indeholder (4, 4, 4, 3)); resultat. fjern (3); assertEquals (3, names.size ()); }

Bemærk, at output fra Collections.transform () er en levende visning af originalen Kollektion- ændringer til den ene påvirker den anden.

Og - samme som før - hvis vi forsøger at tilføje et element til output Kollektion, en Ikke-understøttetOperationException vil blive kastet.

8. Opret Fungere fra Prædikat

Vi kan også skabe Fungere fra en Prædikat ved brug af Functions.fromPredicate (). Dette bliver selvfølgelig en funktion, der omdanner indgangene til Boolski henhold til prædikatets tilstand.

I det følgende eksempel transformerer vi a Liste af navne til en liste over booleanske, hvor hvert element repræsenterer, hvis navnet indeholder "m":

@Test offentligt ugyldigt nårCreatingAFunctionFromAPredicate_thenCorrect () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.transform (navne, Functions.forPredicate (Predicates.containsPattern ("m"))); assertEquals (4, result.size ()); assertThat (resultat, indeholder (falsk, falsk, sand, sand)); }

9. Sammensætning af to funktioner

Dernæst - lad os se på, hvordan man transformerer en samling ved hjælp af en komponeret Fungere.

Funktioner. Komponere () returnerer sammensætningen af ​​to funktioner, når den gælder den anden Fungere på output af den første Fungere.

I det følgende eksempel - det første Fungere omdanne navnet til dets længde, derefter det andet Fungere omdanner længden til a boolsk værdi, der repræsenterer, hvis navnets længde er jævn:

@Test public void whenTransformingUsingComposedFunction_thenTransformed () {Function f1 = new Function () {@Override public Integer apply (String input) {return input.length (); }}; Funktion f2 = ny funktion () {@Override public Boolean apply (Integer input) {return input% 2 == 0; }}; Liste navne = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.transform (navne, Funktioner.komponer (f2, f1)); assertEquals (4, result.size ()); assertThat (resultat, indeholder (true, true, true, false)); }

10. Kombiner filtrering og transformation

Og nu - lad os se en anden cool API, som Guava har - en, der faktisk giver os mulighed for kædefiltrering og transformation sammen - FlydendeIterabel.

I det følgende eksempel filtrerer vi Liste navne omdanne det derefter ved hjælp af FlydendeIterabel:

@Test public void whenFilteringAndTransformingCollection_thenCorrect () {Predicate predicate = new Predicate () {@ Override public boolean apply (String input)}; Funktion func = ny funktion () {@Override public Integer apply (String input) {return input.length (); }}; Liste navne = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = FluentIterable.from (names) .filter (predicate) .transform (func) .toList (); assertEquals (2, result.size ()); assertThat (resultat, indeholderInAnyOrder (4, 3)); }

Det er værd at nævne, at den bydende version i nogle tilfælde er mere læsbar og bør foretrækkes frem for den funktionelle tilgang.

11. Konklusion

Endelig lærte vi at filtrere og transformere samlinger ved hjælp af Guava. Vi brugte Collections2.filter () og Iterables.filter () API'er til filtrering såvel som Collections2.transform () og Iterables.transform () at transformere samlinger.

Endelig kiggede vi hurtigt på det meget interessante FlydendeIterabel flydende API til at kombinere både filtrering og transformation.

Implementeringen af ​​alle disse eksempler og kodestykker kan findes i GitHub-projektet - dette er et Maven-baseret projekt, så det skal være let at importere og køre som det er.