DistinctBy u Java Stream API-ju

1. Pregled

Traženje različitih elemenata na popisu jedan je od uobičajenih zadataka s kojima se mi kao programeri obično susrećemo. Od Jave 8 pa nadalje s uključenjem Potoci imamo novi API za obradu podataka uporabom funkcionalnog pristupa.

U ovom ćemo članku prikazati različite mogućnosti filtriranja zbirke pomoću određenog atributa objekata na popisu.

2. Korištenje Stream API-ja

Stream API pruža različit () metoda koja vraća različite elemente popisa na temelju jednako () metoda Objekt razred.

Međutim, postaje manje fleksibilan ako želimo filtrirati prema određenom atributu. Jedna od alternativa koju imamo je pisanje filtra koji održava stanje.

2.1. Korištenje filtra s podacima o stanju

Jedno od mogućih rješenja bilo bi provođenje statusa state Predikat:

javni statični predikat distinctByKey (Function keyExtractor) {Vidjena karta = novo ConcurrentHashMap (); vrati t -> vidio.putIfAbsent (keyExtractor.apply (t), Boolean.TRUE) == null; }

Da bismo ga testirali, poslužit ćemo se sljedećim Osoba klasa koja ima atribute dob, e-mail, i Ime:

javni razred Osoba {private int age; privatni naziv niza; privatni String e-mail; // standardni geteri i postavljači}

I da biste dobili novu filtriranu kolekciju Ime, možemo koristiti:

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

3. Korištenje zbirki Eclipse

Eclipse Collections je knjižnica koja pruža dodatne metode za obradu Potoci i zbirke na Javi.

3.1. Koristiti ListIterate.distinct ()

The ListIterate.distinct () metoda omogućuje nam filtriranje a Stream koristeći razne Strategije raspršivanja. Te se strategije mogu definirati pomoću lambda izraza ili referenci na metode.

Ako želimo filtrirati po Osobe Ime:

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

Ili, ako je atribut koji ćemo koristiti primitivan (int, long, double), možemo koristiti specijaliziranu funkciju poput ove:

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

3.2. Ovisnost Mavena

Moramo dodati sljedeće ovisnosti u naš pom.xml za korištenje kolekcija Eclipse u našem projektu:

 org.eclipse.zbirke eclipse-collection 8.2.0 

Najnoviju verziju biblioteke Eclipse Collections možete pronaći u središnjem spremištu Maven.

Da biste saznali više o ovoj knjižnici, možemo otići na ovaj članak.

4. Koristeći Vavr (Javaslang)

Ovo je funkcionalna knjižnica za Java 8 koja pruža nepromjenjive podatke i funkcionalne upravljačke strukture.

4.1. Koristeći List.distinctBy

Za filtriranje popisa, ova klasa nudi vlastitu klasu Popis koja ima distinctBy () metoda koja nam omogućuje filtriranje po atributima objekata koje sadrži:

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

4.2. Ovisnost Mavena

Našu ćemo dodati sljedeće ovisnosti pom.xml koristiti Vavr u našem projektu.

 io.vavr vavr 0.9.0 

Najnoviju verziju biblioteke Vavr možete pronaći u spremištu Maven Central.

Da biste saznali više o ovoj knjižnici, možemo otići na ovaj članak.

5. Korištenje StreamEx-a

Ova knjižnica nudi korisne klase i metode za obradu Java 8 strujanja.

5.1. Koristeći StreamEx.distinct

U okviru nastave je StreamEx koja ima različit metoda na koju možemo poslati referencu na atribut tamo gdje se želimo razlikovati:

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

5.2. Ovisnost Mavena

Našu ćemo dodati sljedeće ovisnosti pom.xml koristiti StreamEx u našem projektu.

 one.util streamex 0.6.5 

Najnoviju verziju biblioteke StreamEx možete pronaći u spremištu Maven Central.

6. Zaključak

U ovom smo brzom vodiču istražili primjere kako dobiti različite elemente streama, na temelju atributa koristeći standardni Java 8 API i dodatne alternative s drugim knjižnicama.

Kao i uvijek, cjeloviti kôd dostupan je na GitHub-u.