Filtrering og transformering av samlinger i Guava

1. Oversikt

I denne opplæringen vil vi illustrere hvordan du gjør det filtrer og transformer samlinger med Guava.

Vi filtrerer ved hjelp av predikater, transformerer ved hjelp av funksjonene som biblioteket gir, og til slutt får vi se hvordan vi kan kombinere både filtrering og transformering.

2. Filtrer en samling

La oss starte med et enkelt eksempel på filtrering av en samling. Vi vil bruke et ut av boksen Predikat levert av biblioteket og konstruert via Predikater bruksklasse:

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

Som du ser, filtrerer vi Liste av navn for å få bare navnene som inneholder tegnet “a” - og vi bruker Iterables.filter () å gjøre det.

Alternativt kan vi gjøre god bruk av Collections2.filter () API også:

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

Noen få ting å merke seg her - først produksjonen av Collections.filter () er en live visning av den originale samlingen - endringer i den ene vil gjenspeiles i den andre.

Det er også viktig å forstå det nå, resultatet er begrenset av predikatet - hvis vi legger til et element som ikke tilfredsstiller det Predikere, en IllegalArgumentException vil bli kastet:

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

3. Skriv tilpasset filter Predikere

Neste - la oss skrive våre egne Predikere i stedet for å bruke en fra biblioteket. I det følgende eksemplet - definerer vi et predikat som bare får navnene som begynner med “A” eller “J”:

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

4. Kombiner flere predikater

Vi kan kombinere flere predikater ved hjelp av Predicates.or () og Predicates.and ().

I det følgende eksemplet - filtrerer vi a Liste av navn for å få navnene som begynner med “J” eller som ikke inneholder “a”:

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

5. Fjern nullverdier mens du filtrerer en samling

Vi kan rydde opp i null verdier fra en samling ved å 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 (navn, Predicates.notNull ()); assertEquals (4, result.size ()); assertThat (resultat, inneholderInAnyOrder ("John", "Jane", "Adam", "Tom")); }

6. Sjekk om alle elementer i en samling samsvarer med en tilstand

La oss deretter sjekke om alle elementene i en samling samsvarer med en viss tilstand. Vi bruker Iterables.all () for å sjekke om alle navn inneholder “n” eller “m”, så sjekker vi om alle elementene inneholder “a”:

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

7. Transformer en samling

Nå - la oss se hvordan transformere en samling ved hjelp av en Guava Funksjon. I det følgende eksemplet transformerer vi a Liste av navn til en Liste av Heltall (navnets lengde) med Iterables.transform ():

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

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

@Test public void whenTransformWithCollections2_thenTransformed () {Function func = new Function () {@ Override public Integer apply (String input) {return input.length (); }}; Listenavn = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.transform (navn, funksjon); assertEquals (4, result.size ()); assertThat (resultatet inneholder (4, 4, 4, 3)); resultat. fjern (3); assertEquals (3, names.size ()); }

Merk at utgangen fra Collections.transform () er en live visning av originalen Samling- endringer i den ene påvirker den andre.

Og - samme som før - hvis vi prøver å legge til et element i utgangen Samling, en Ikke-støttetOperationException vil bli kastet.

8. Opprett Funksjon fra Predikere

Vi kan også lage Funksjon fra en Predikere ved hjelp av Functions.fromPredicate (). Dette blir selvfølgelig en funksjon som forvandler inngangene til Boolsk, i henhold til predikatets tilstand.

I det følgende eksemplet transformerer vi a Liste med navn til en liste over booleans der hvert element representerer hvis navnet inneholder “m”:

@Test offentlig ugyldig nårCreatingAFunctionFromAPredicate_thenCorrect () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.transform (navn, Functions.forPredicate (Predicates.containsPattern ("m"))); assertEquals (4, result.size ()); assertThat (resultat, inneholder (false, false, true, true)); }

9. Sammensetning av to funksjoner

Neste - la oss ta en titt på hvordan du transformerer en samling ved hjelp av en komponert Funksjon.

Functions.compose () returnerer komposisjonen av to funksjoner når den gjelder den andre Funksjon på utgangen av den første Funksjon.

I det følgende eksemplet - det første Funksjon forvandle navnet til lengden, deretter det andre Funksjon forvandler lengden til a boolsk verdi som representerer hvis navnets lengde er jevn:

@Test public void whenTransformingUsingComposedFunction_thenTransformed () {Function f1 = new Function () {@Override public Integer apply (Strenginngang) {return input.length (); }}; Funksjon f2 = ny funksjon () {@Override public Boolean Apply (Integer input) {returinngang% 2 == 0; }}; Listenavn = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = Collections2.transform (navn, Funksjoner.komponer (f2, f1)); assertEquals (4, result.size ()); assertThat (resultat, inneholder (true, true, true, false)); }

10. Kombiner filtrering og transformering

Og nå - la oss se en annen kul API som Guava har - en som faktisk vil tillate oss å kjedefiltrere og transformere sammen - Flytende.

I det følgende eksemplet - filtrerer vi Liste av navn forvandler den deretter ved hjelp av Flytende:

@Test public void whenFilteringAndTransformingCollection_thenCorrect () {Predicate predicate = new Predicate () {@Override public boolean apply (Strenginngang)}; Funksjon func = ny funksjon () {@ Override public Integer apply (String input) {return input.length (); }}; Listenavn = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Samlingsresultat = FluentIterable.from (navn) .filter (predikat) .transform (func) .toList (); assertEquals (2, result.size ()); assertThat (resultat, inneholderInAnyOrder (4, 3)); }

Det er verdt å nevne at i noen tilfeller er den tvingende versjonen mer lesbar og bør foretrekkes fremfor den funksjonelle tilnærmingen.

11. Konklusjon

Til slutt lærte vi hvordan vi kan filtrere og transformere samlinger ved hjelp av Guava. Vi brukte Collections2.filter () og Iterables.filter () APIer for filtrering, så vel som Collections2.transform () og Iterables.transform () å transformere samlinger.

Til slutt tok vi en rask titt på det veldig interessante Flytende flytende API for å kombinere både filtrering og transformering.

Implementeringen av alle disse eksemplene og kodebiter kan du finne i GitHub-prosjektet - dette er et Maven-basert prosjekt, så det skal være enkelt å importere og kjøre som det er.


$config[zx-auto] not found$config[zx-overlay] not found