DistinctBy i Java Stream API

1. Oversigt

Søgning efter forskellige elementer på en liste er en af ​​de almindelige opgaver, som vi som programmører normalt står over for. Fra Java 8 med inklusion af Strømme Vi har en ny API til at behandle data ved hjælp af funktionel tilgang.

I denne artikel viser vi forskellige alternativer til filtrering af en samling ved hjælp af en bestemt attribut for objekter på listen.

2. Brug af Stream API

Stream API leverer tydelig () metode, der returnerer forskellige elementer på en liste baseret på lige med() metode til Objekt klasse.

Det bliver dog mindre fleksibelt, hvis vi vil filtrere efter en bestemt attribut. Et af de alternativer, vi har, er at skrive et filter, der opretholder tilstanden.

2.1. Brug af et statefult filter

En af de mulige løsninger ville være at implementere en stateful Prædikat:

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

For at teste det bruger vi følgende Person klasse, der har attributterne alder, e-mailog navn:

offentlig klasseperson {privat int alder; privat strengnavn; privat streng e-mail; // standard getters og setter}

Og for at få en ny filtreret samling af navn, kan vi bruge:

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

3. Brug af Eclipse Collections

Eclipse Collections er et bibliotek, der giver yderligere metoder til behandling Strømme og samlinger i Java.

3.1. Bruger ListIterate.distinct ()

Det ListIterate.distinct () metode giver os mulighed for at filtrere en Strøm ved hjælp af forskellige HashingStrategies. Disse strategier kan defineres ved hjælp af lambda-udtryk eller metodehenvisninger.

Hvis vi vil filtrere efter Personens navn:

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

Eller hvis den attribut, vi skal bruge, er primitiv (int, lang, dobbelt), kan vi bruge en specialfunktion som denne:

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

3.2. Maven afhængighed

Vi er nødt til at tilføje følgende afhængigheder til vores pom.xml at bruge Eclipse Collections i vores projekt:

 org.eclipse.collections formørkelsessamlinger 8.2.0 

Du kan finde den nyeste version af Eclipse Collections-biblioteket i Maven Central-arkivet.

For at lære mere om dette bibliotek kan vi gå til denne artikel.

4. Brug af Vavr (Javaslang)

Dette er et funktionelt bibliotek til Java 8, der giver uforanderlige data og funktionelle kontrolstrukturer.

4.1. Ved brug af List.distinctBy

For at filtrere lister giver denne klasse sin egen listeklasse, der har tydeligBy () metode, der giver os mulighed for at filtrere efter attributter for de objekter, den indeholder:

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

4.2. Maven afhængighed

Vi tilføjer følgende afhængigheder til vores pom.xml at bruge Vavr i vores projekt.

 io.vavr vavr 0.9.0 

Du kan finde den nyeste version af Vavr-biblioteket i Maven Central-arkivet.

For at lære mere om dette bibliotek kan vi gå til denne artikel.

5. Brug af StreamEx

Dette bibliotek giver nyttige klasser og metoder til behandling af Java 8-streams.

5.1. Ved brug af StreamEx.distinct

Inden for de tilbudte klasser er StreamEx som har tydelig metode, som vi kan sende en henvisning til attributten, hvor vi vil adskille:

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

5.2. Maven afhængighed

Vi tilføjer følgende afhængigheder til vores pom.xml at bruge StreamEx i vores projekt.

 one.util streamex 0.6.5 

Du kan finde den nyeste version af StreamEx-biblioteket i Maven Central-arkivet.

6. Konklusion

I denne hurtige vejledning udforskede vi eksempler på, hvordan man får forskellige elementer i en Stream, baseret på en attribut ved hjælp af standard Java 8 API og yderligere alternativer med andre biblioteker.

Som altid er den komplette kode tilgængelig på GitHub.