Rad s kartama pomoću streamova

1. Uvod

U ovom uputstvu razmotrit ćemo neke primjere upotrebe Java Streamsraditi s Kartas. Vrijedno je napomenuti da bi se neke od ovih vježbi mogle riješiti dvosmjernim Karta strukturu podataka, ali ovdje nas zanima funkcionalan pristup.

Prvo objašnjavamo osnovnu ideju s kojom ćemo raditi Karte i Streams. Zatim predstavljamo nekoliko različitih problema povezanih s Karte i njihova konkretna rješenja pomoću Streams.

2. Osnovna ideja

Glavna stvar koju treba primijetiti je to Streams su nizovi elemenata koji se lako mogu dobiti iz a Kolekcija.

Karte imaju drugačiju strukturu, s preslikavanjem ključeva u vrijednosti, bez slijeda. To ne znači da ne možemo pretvoriti a Karta strukturirati u različite sekvence koji nam tada omogućuju prirodan rad s Stream API-jem.

Pogledajmo načine dobivanja različitih Kolekcijas iz Karta, koju zatim možemo okrenuti u Stream:

Mapa someMap = nova HashMap ();

Možemo dobiti skup parova ključ / vrijednost:

Postavi unosi = someMap.entrySet ();

Također možemo dobiti skup ključeva povezan s Karta:

Postavi keySet = someMap.keySet ();

Ili bismo mogli izravno raditi sa skupom vrijednosti:

Vrijednosti zbirke = someMap.values ​​();

Svaki od njih daje nam ulaznu točku za obradu tih zbirki dobivanjem streamova od njih:

Stream entriesStream = entries.stream (); Stream valuesStream = values.stream (); Streams keysStream = keySet.stream ();

3. Dobivanje a KartaS pomoću tipki Streams

3.1. Ulazni podaci

Pretpostavimo da imamo a Karta:

Knjige mapa = novi HashMap (); books.put ("978-0201633610", "Uzorci dizajna: elementi objektno orijentiranog softvera za višekratnu upotrebu"); books.put ("978-1617291999", "Java 8 u akciji: Lambda, potoci i programiranje u funkcionalnom stilu"); books.put ("978-0134685991", "Učinkovita Java");

Zanima nas ISBN za knjigu s naslovom "Učinkovita Java".

3.2. Dohvaćanje šibice

Budući da naslov knjige nije mogao postojati u našoj Karta, želimo biti u mogućnosti naznačiti da za njega ne postoji pridruženi ISBN. Možemo koristiti Neobvezno da to izrazi:

Pretpostavimo za ovaj primjer da nas zanima bilo koji ključ za knjigu koja odgovara tom naslovu:

Neobvezno optionalIsbn = books.entrySet (). Stream () .filter (e -> "Učinkovita Java" .jednak (e.getValue ())) .map (Map.Entry :: getKey) .findFirst (); assertEquals ("978-0134685991", optionalIsbn.get ());

Analizirajmo kod. Prvi, dobivamo entrySet od Karta, kao što smo ranije vidjeli.

Želimo uzeti u obzir samo unose s naslovom "Učinkovita Java", tako da će prva posrednička operacija biti filtar.

Ne zanima nas cjelina Karta unos, ali u ključu svakog unosa. Dakle, sljedeća vezana međuoperacija čini upravo to: to je a karta operacija koja će generirati novi tok kao izlaz koji će sadržavati samo ključeve za unose koji odgovaraju naslovu koji smo tražili.

Kako želimo samo jedan rezultat, možemo primijeniti findFirst () terminalni rad, koji će pružiti početnu vrijednost u Stream kao an Neobvezno objekt.

Pogledajmo slučaj u kojem naslov ne postoji:

Izborno optionalIsbn = books.entrySet (). Stream () .filter (e -> "Nepostojeći naslov" .equals (e.getValue ())) .map (Map.Entry :: getKey) .findFirst (); assertEquals (false, optionalIsbn.isPresent ());

3.3. Dohvaćanje više rezultata

Promijenimo sada problem da vidimo kako bismo se mogli nositi s vraćanjem više rezultata umjesto jednog.

Da bi se vratilo više rezultata, dodajte sljedeću knjigu u našu Karta:

books.put ("978-0321356680", "Učinkovita Java: drugo izdanje"); 

Pa sada, ako tražimo svi knjige koje počinju s "Učinkovita Java", dobit ćemo više rezultata:

Popis isbnCodes = books.entrySet (). Stream () .filter (e -> e.getValue (). StartWith ("Effective Java")) .map (Map.Entry :: getKey) .collect (Collectors.toList () ); assertTrue (isbnCodes.contens ("978-0321356680")); assertTrue (isbnCodes.contains ("978-0134685991"));

U ovom smo slučaju učinili zamjenu stanja filtra kako bismo provjerili je li vrijednost u Karta započinje s "Effective Java" umjesto uspoređivanja za Niz jednakost.

Ovaj put, mi prikupiti Rezultati - umjesto da odaberete prvu - stavite šibice u Popis.

4. Dobivanje a KartaVrijednosti pomoću Streams

Usredotočimo se sada na drugi problem s kartama: Umjesto da dobije ISBN-ovi bazirano na naslovi, pokušat ćemo i dobiti naslovi bazirano na ISBN-ovi.

Upotrijebimo original Karta. Želimo pronaći naslove za koje njihov ISBN započinje s “978-0”.

Popis naslova = books.entrySet (). Stream () .filter (e -> e.getKey (). StartWith ("978-0")) .map (Map.Entry :: getValue) .collect (Collectors.toList ( )); assertEquals (2, title.size ()); assertTrue (title.contens ("Uzorci dizajna: elementi objektno orijentiranog softvera za višekratnu upotrebu")); assertTrue (title.contens ("Effective Java"));

Ovo je rješenje slično rješenjima za naš prethodni skup problema - mi strujimo skup unosa, a zatim filtriramo, mapiramo i prikupljamo.

I kao prije, ako smo željeli vratiti samo prvu utakmicu, mogli bismo i nakon karta metoda pozvati findFirst () metoda, umjesto da se svi rezultati prikupe u a Popis.

5. Zaključak

Pokazali smo kako se obrađuje a Karta na funkcionalan način.

Konkretno, vidjeli smo da nakon što prijeđemo na korištenje pridruženih zbirki u Kartas, obrada pomoću Streams postaje puno lakše i intuitivnije.

I, naravno, svi primjeri mogu se naći u projektu GitHub.