Hvordan filtrere en samling i Java

1. Oversikt

I denne korte opplæringen, vi ser på forskjellige måter å filtrere en samling på Java på - det vil si å finne alle elementene som oppfyller en viss tilstand.

Dette er en grunnleggende oppgave som er tilstede i praktisk talt alle Java-applikasjoner.

Av denne grunn er antall biblioteker som tilbyr funksjonalitet for dette formålet betydelig.

Spesielt vil vi i denne opplæringen dekke:

  • Java 8 Streams ' filter() funksjon
  • Java 9 filtrering samler
  • Relevant Formørkelsamlinger APIer
  • Apache er CollectionUtils filter () metode
  • Guava Collections2 filter () nærme seg

2. Bruke Streams

Siden Java 8 ble introdusert, har Streams fått en nøkkelrolle i de fleste tilfeller der vi må behandle en innsamling av data.

Derfor er dette den foretrukne tilnærmingen i de fleste tilfeller, da den er bygget i Java og ikke krever noen ekstra avhengigheter.

2.1. Filtrere en samling med Strømmer

For enkelhets skyld, i alle eksemplene vil målet vårt være å lage en metode som bare henter partall fra a Samling av Heltall verdier.

Dermed kan vi uttrykke tilstanden vi vil bruke til å evaluere hvert element som ‘verdi% 2 == 0‘.

I alle tilfeller må vi definere denne tilstanden som en Predikere gjenstand:

offentlig samling findEvenNumbers (Collection baseCollection) {Predicate streamsPredicate = item -> item% 2 == 0; return baseCollection.stream () .filter (streamsPredicate) .collect (Collectors.toList ()); }

Det er viktig å merke seg det hvert bibliotek vi analyserer i denne opplæringen gir sitt eget Predikere gjennomføring, men at allikevel, alle er definert som funksjonelle grensesnitt, og lar oss derfor bruke Lambda-funksjoner til å erklære dem.

I dette tilfellet brukte vi en forhåndsdefinert Samler levert av Java som samler elementene i en Liste, men vi kunne ha brukt andre, som diskutert i dette forrige innlegget.

2.2. Filtrering etter gruppering av en samling i Java 9

Strømmer tillater oss å samle varer ved hjelp av gruppering av samler.

Likevel, hvis vi filtrerer som vi gjorde i forrige avsnitt, kan noen elementer bli kastet på et tidlig stadium, før denne samleren kommer i spill.

Av denne grunn, de filtrering samler ble introdusert med Java 9, med det formål å behandle delsamlingene etter at de er gruppert.

Etter vårt eksempel, la oss forestille oss at vi vil gruppere samlingen vår basert på antall sifre hvert heltall har, før vi filtrerer ut oddetallene:

offentlig kart findEvenNumbersAfterGrouping (Collection baseCollection) {Funksjon getQuantityOfDigits = element -> (int) Math.log10 (element) + 1; return baseCollection.stream () .collect (groupingBy (getQuantityOfDigits, filtering (item -> item% 2 == 0, toList ()))); }

Kort sagt, hvis vi bruker denne samleren, kan vi ende opp med en tom verdioppføring, mens hvis vi filtrerer før gruppering, ville samleren ikke opprette en slik oppføring i det hele tatt.

Selvfølgelig ville vi velge tilnærming basert på våre krav.

3. Bruke Formørkelsessamlinger

Vi kan også bruke noen andre tredjepartsbiblioteker for å nå vårt mål, enten hvis det er fordi applikasjonen vår ikke støtter Java 8, eller fordi vi ønsker å dra nytte av kraftig funksjonalitet som ikke leveres av Java.

Slik er tilfellet med Formørkelsessamlinger, et bibliotek som prøver å holde tritt med de nye paradigmene, utvikle seg og omfavne endringene som er introdusert av alle de nyeste Java-utgivelsene.

Vi kan begynne med å utforske vårt introduksjonsinnlegg for Eclipse Collections for å få en bredere kunnskap om funksjonaliteten som tilbys av dette biblioteket.

3.1. Avhengigheter

La oss begynne med å legge til følgende avhengighet til prosjektet vårt pom.xml:

 org.eclipse.collections formørkelsesamlinger 9.2.0 

De formørkelsamlinger inkluderer alle nødvendige grensesnitt for datastruktur og selve API-en.

3.2. Filtrere en samling med Formørkelsamlinger

La oss nå bruke formørkelses filtreringsfunksjonalitet på en av datastrukturene, for eksempel dens MutableList:

offentlig samling findEvenNumbers (Collection baseCollection) {Predicate eclipsePredicate = item -> item% 2 == 0; Samling filteredList = Lists.mutable .ofAll (baseCollection) .select (eclipsePredicate); retur filteredList; }

Som et alternativ kunne vi ha brukt Repetere‘S å velge()statisk metode for å definere filteredList gjenstand:

Samling filteredList = Iterate.select (baseCollection, eclipsePredicate);

4. Bruke Apache CollectionUtils

For å komme i gang med Apache's CollectionUtils bibliotek, kan vi sjekke ut denne korte opplæringen der vi dekket bruken.

I denne opplæringen vil vi imidlertid fokusere på dens filter() gjennomføring.

4.1. Avhengigheter

Først trenger vi følgende avhengigheter i vår pom.xml fil:

 org.apache.commons commons-collection4 4.2 

4.2. Filtrere en samling med CollectionUtils

Vi er nå klare til å bruke CollectonUtils‘Metoder:

offentlig samling findEvenNumbers (Collection baseCollection) {Predicate apachePredicate = item -> item% 2 == 0; CollectionUtils.filter (baseCollection, apachePredicate); retur base Samling; }

Vi må ta i betraktning at denne metoden endrer baseCollection ved å fjerne hvert element som ikke samsvarer med tilstanden.

Dette betyr at basissamlingen må være foranderlig, ellers vil det kaste et unntak.

5. Bruke guava Samlinger2

Som tidligere kan vi lese vårt forrige innlegg ‘Filtrering og transformering av samlinger i Guava’ for ytterligere informasjon om dette emnet.

5.1. Avhengigheter

La oss starte med å legge til denne avhengigheten i vår pom.xml fil:

 com.google.guava guava 25.1-jre 

5.2. Filtrere en samling med Samlinger2

Som vi kan se, er denne tilnærmingen ganske lik den som ble fulgt i siste avsnitt:

offentlig samling findEvenNumbers (Collection baseCollection) {Predicate guavaPredicate = item -> item% 2 == 0; returner Collections2.filter (baseCollection, guavaPredicate); }

Igjen, her definerer vi en Guava-spesifikk Predikere gjenstand.

I dette tilfellet endrer Guava ikke baseCollection, det genererer en ny, slik at vi kan bruke en uforanderlig samling som input.

6. Konklusjon

Oppsummert har vi sett at det er mange forskjellige måter å filtrere samlinger på Java.

Selv om Streams vanligvis er den foretrukne tilnærmingen, er det godt å vite og huske på funksjonaliteten som andre biblioteker tilbyr.

Spesielt hvis vi trenger å støtte eldre Java-versjoner. Imidlertid, hvis dette er tilfelle, må vi huske at nylige Java-funksjoner som brukes gjennom hele opplæringen, for eksempel lambdas, bør erstattes med anonyme klasser.

Som vanlig kan vi finne alle eksemplene som vises i denne opplæringen i Github-repoen.