DistinctBy i Java Stream API

1. Oversikt

Å søke etter forskjellige elementer i en liste er en av de vanlige oppgavene som vi som programmerere vanligvis står overfor. Fra Java 8 med inkludering av Strømmer vi har en ny API for å behandle data ved hjelp av funksjonell tilnærming.

I denne artikkelen viser vi forskjellige alternativer til å filtrere en samling ved hjelp av et bestemt attributt av objekter i listen.

2. Bruke Stream API

Stream API gir distinkt() metode som returnerer forskjellige elementer i en liste basert på er lik() metoden for Gjenstand klasse.

Imidlertid blir det mindre fleksibelt hvis vi vil filtrere etter et bestemt attributt. Et av alternativene vi har er å skrive et filter som opprettholder staten.

2.1. Bruke et stateful filter

En av de mulige løsningene vil være å implementere en stateful Predikat:

public static Predicate distinctByKey (Function keyExtractor) {Map seen = new ConcurrentHashMap (); return t -> seen.putIfAbsent (keyExtractor.apply (t), Boolean.TRUE) == null; }

For å teste det, bruker vi følgende Person klasse som har attributtene alder, e-post, og Navn:

offentlig klasse Person {privat int alder; privat strengnavn; privat streng e-post; // standard getters og setters}

Og for å få en ny filtrert samling av Navn, Vi kan bruke:

Liste personListFiltered = personList.stream () .filter (distinctByKey (p -> p.getName ())) .collect (Collectors.toList ());

3. Bruke formørkelsamlinger

Eclipse Collections er et bibliotek som gir flere metoder for behandling Strømmer og samlinger i Java.

3.1. Bruker ListIterate.distinct ()

De ListIterate.distinct () metoden lar oss filtrere a Strøm bruker forskjellige HashingStrategies. Disse strategiene kan defineres ved hjelp av lambdauttrykk eller metodereferanser.

Hvis vi vil filtrere etter Personens Navn:

List personListFiltered = ListIterate .distinct (personList, HashingStrategies.fromFunction (Person :: getName));

Eller hvis attributtet vi skal bruke er primitiv (int, lang, dobbel), kan vi bruke en spesialfunksjon som denne:

List personListFiltered = ListIterate.distinct (personList, HashingStrategies.fromIntFunction (Person :: getAge));

3.2. Maven avhengighet

Vi må legge til følgende avhengigheter i vår pom.xml å bruke Eclipse Collections i prosjektet vårt:

 org.eclipse.collections formørkelsesamlinger 8.2.0 

Du finner den siste versjonen av Eclipse Collections-biblioteket i Maven Central-arkivet.

For å lære mer om dette biblioteket kan vi gå til denne artikkelen.

4. Bruke Vavr (Javaslang)

Dette er et funksjonelt bibliotek for Java 8 som gir uforanderlige data og funksjonelle kontrollstrukturer.

4.1. Ved hjelp av List.distinctBy

For å filtrere lister, gir denne klassen sin egen listeklasse som har distinkt av () metode som lar oss filtrere etter attributter til objektene den inneholder:

List personListFiltered = List.ofAll (personList) .distinctBy (Person :: getName) .toJavaList ();

4.2. Maven avhengighet

Vi vil legge til følgende avhengigheter i vår pom.xml å bruke Vavr i prosjektet vårt.

 io.vavr vavr 0.9.0 

Du finner den nyeste versjonen av Vavr-biblioteket i Maven Central-arkivet.

For å lære mer om dette biblioteket kan vi gå til denne artikkelen.

5. Bruke StreamEx

Dette biblioteket gir nyttige klasser og metoder for behandling av Java 8-strømmer.

5.1. Ved hjelp av StreamEx. Tydelig

Innenfor klassene som tilbys er StreamEx som har distinkt metode som vi kan sende en referanse til attributtet der vi vil skille:

Liste personListFiltered = StreamEx.of (personList) .distinct (Person :: getName) .toList ();

5.2. Maven avhengighet

Vi vil legge til følgende avhengigheter i vår pom.xml å bruke StreamEx i prosjektet vårt.

 one.util streamex 0.6.5 

Du finner den siste versjonen av StreamEx-biblioteket i Maven Central-arkivet.

6. Konklusjon

I denne raske opplæringen utforsket vi eksempler på hvordan du får forskjellige elementer i en Stream, basert på et attributt ved hjelp av standard Java 8 API og tilleggsalternativer med andre biblioteker.

Som alltid er den komplette koden tilgjengelig på GitHub.


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