Práca s mapami pomocou streamov

1. Úvod

V tomto výučbe si ukážeme niekoľko príkladov používania jazyka Java Prúdspracovať s Mapas. Stojí za zmienku, že niektoré z týchto cvičení bolo možné vyriešiť obojsmerne Mapa dátovú štruktúru, ale zaujíma nás tu funkčný prístup.

Najskôr vysvetlíme základnú myšlienku, s ktorou budeme pracovať Mapy a Prúds. Potom predstavíme niekoľko rôznych problémov týkajúcich sa Mapy a ich konkrétne riešenia pomocou Prúds.

2. Základná myšlienka

Je potrebné si všimnúť hlavne to Prúds sú sekvencie prvkov, ktoré možno ľahko získať z a Zbierka.

Mapy majú inú štruktúru s mapovaním od kľúčov k hodnotám bez postupnosti. To neznamená, že nemôžeme previesť a Mapa štruktúru do rôznych sekvencií, ktoré nám potom umožňujú pracovať prirodzeným spôsobom s Stream API.

Pozrime sa na spôsoby, ako získať rôzne Zbierkas z a Mapa, ktoré potom môžeme otočiť do a Prúd:

Map someMap = new HashMap ();

Môžeme získať množinu párov kľúč - hodnota:

Nastaviť entries = someMap.entrySet ();

Môžeme tiež získať súpravu kľúčov spojenú s Mapa:

Set keySet = someMap.keySet ();

Alebo by sme mohli pracovať priamo s množinou hodnôt:

Hodnoty zbierky = someMap.values ​​();

Každý z nich nám dáva vstupný bod na spracovanie týchto zbierok získavaním streamov z nich:

Prúd entriesStream = entries.stream (); Streamovať hodnotyStream = values.stream (); Streamovať kľúčeStream = keySet.stream ();

3. Získanie a MapaPoužívanie klávesov Prúds

3.1. Vstupné Data

Predpokladajme, že máme a Mapa:

Mapové knihy = nová HashMap (); books.put ("978-0201633610", "Dizajnové vzory: prvky opakovane použiteľného objektovo orientovaného softvéru"); books.put ("978-1617291999", "Java 8 v akcii: Lambdas, Streams a programovanie vo funkčnom štýle"); books.put ("978-0134685991", "Efektívna Java");

Máme záujem o nájdenie ISBN knihy s názvom „Effective Java“.

3.2. Získanie zápasu

Pretože názov knihy nemohol existovať v našom Mapa, chceme byť schopní označiť, že pre ňu nie je spojené žiadne číslo ISBN. Môžeme použiť Voliteľné aby som to vyjadril:

Predpokladajme pre tento príklad, že nás zaujíma akýkoľvek kľúč pre knihu zodpovedajúci danému názvu:

Voliteľné optionalIsbn = books.entrySet (). Stream () .filter (e -> „Efektívna Java“ .equals (e.getValue ())) .map (Map.Entry :: getKey) .findFirst (); assertEquals ("978-0134685991", optionalIsbn.get ());

Poďme analyzovať kód. Najprv, získavame entrySet z Mapa, ako sme videli predtým.

Chceme brať do úvahy iba položky s nadpisom „Efektívna Java“, takže prvou prechodnou operáciou bude filter.

Nás nezaujíma celok Mapa záznam, ale v kľúči každého záznamu. Ďalšia zreťazená sprostredkovaná operácia teda robí iba toto: je to mapa operácia, ktorá vygeneruje nový stream ako výstup, ktorý bude obsahovať iba kľúče pre položky zodpovedajúce hľadanému názvu.

Pretože chceme iba jeden výsledok, môžeme použiť findFirst () terminálna prevádzka, ktorá poskytne počiatočnú hodnotu v Prúd ako Voliteľné objekt.

Pozrime sa na prípad, keď názov neexistuje:

Voliteľné optionalIsbn = books.entrySet (). Stream () .filter (e -> „Neexistujúci názov“ .equals (e.getValue ())) .map (Map.Entry :: getKey) .findFirst (); assertEquals (false, optionalIsbn.isPresent ());

3.3. Načítanie viacerých výsledkov

Poďme teraz problém zmeniť, aby sme videli, ako by sme sa mohli vyrovnať s vrátením viacerých výsledkov namiesto jedného.

Aby sme vrátili viac výsledkov, pridajme do našej knihy nasledujúcu knihu Mapa:

books.put ("978-0321356680", "Effective Java: Second Edition"); 

Takže teraz, keď hľadáme všetko knihy, ktoré začínajú na „Efektívna Java“, dostaneme späť viac ako jeden výsledok:

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

Čo sme v tomto prípade urobili, je nahradiť podmienku filtra, aby sme overili, či je hodnota v Mapa namiesto porovnania pre začína „Effective Java“ String rovnosť.

Tentokrát, my zbierať výsledky - namiesto výberu prvého - vloženie zápasov do a Zoznam.

4. Získanie a MapaPoužívanie hodnôt Prúds

Teraz sa zameriame na iný problém s mapami: Namiesto získania ISBN založený na titulov, pokúsime sa získať titulov založený na ISBN.

Použime originál Mapa. Chceme nájsť tituly, ktorých ISBN začína na „978-0“.

Zoznam titulov = books.entrySet (). Stream () .filter (e -> e.getKey (). StartsWith ("978-0")) .map (Map.Entry :: getValue) .collect (Collectors.toList ( )); assertEquals (2, tituly.size ()); assertTrue (tituly.obsahuje („Dizajnové vzory: prvky opakovane použiteľného objektovo orientovaného softvéru“)); assertTrue (tituly.obsahuje ("Efektívna Java"));

Toto riešenie je podobné riešeniam našej predchádzajúcej množiny problémov - vstupnú množinu streamujeme a potom filtrujeme, mapujeme a zhromažďujeme.

A rovnako ako predtým, ak sme chceli vrátiť iba prvý zápas, mohli sme po mapa metóda volať findFirst () metóda namiesto zhromažďovania všetkých výsledkov v a Zoznam.

5. Záver

Ukázali sme si, ako spracovať a Mapa funkčným spôsobom.

Obzvlášť sme videli, že akonáhle prejdeme na používanie priradených zbierok k Mapas, spracovanie pomocou Prúds sa stáva oveľa ľahším a intuitívnejším.

A samozrejme všetky príklady nájdete v projekte GitHub.