Java 8 Sakupljači toMap
1. Uvod
U ovom brzom vodiču razgovarat ćemo o toMap () metoda Kolekcionari razred. Upotrijebit ćemo ga za prikupljanje Streams u a Karta primjer.
Za sve primjere koji su ovdje obrađeni, kao polazište upotrijebit ćemo popis knjiga i pretvoriti ga u različite Karta implementacije.
2. Popis do Karta
Započet ćemo s najjednostavnijim slučajem, pretvaranjem a Popis u a Karta.
Naše Knjiga klasa se definira kao:
razred knjige {privatni naziv niza; privatno int izdanjeGodina; privatni niz isbn; // geteri i postavljači}
I mi ćemo stvoriti popis knjiga za potvrdu našeg koda:
Popis bookList = novi ArrayList (); bookList.add (nova knjiga ("Družina prstena", 1954., "0395489318")); bookList.add (nova knjiga ("Dvije kule", 1954., "0345339711")); bookList.add (nova knjiga ("Povratak kralja", 1955., "0618129111"));
Za ovaj ćemo scenarij upotrijebiti sljedeće preopterećenje toMap () metoda:
Kolektor toMap (Funkcijska tipkaMapper, Funkcija valueMapper)
S toMap, možemo naznačiti strategije kako dobiti ključ i vrijednost za kartu:
javna karta listToMap (Popis knjiga) {return books.stream (). collect (Collectors.toMap (Book :: getIsbn, Book :: getName)); }
A možemo lako provjeriti funkcionira li sa:
@Test public void whenConvertFromListToMap () {assertTrue (convertToMap.listToMap (bookList) .size () == 3); }
3. Rješavanje ključnih sukoba
Gornji je primjer dobro funkcionirao, ali što bi se dogodilo ako postoji duplicirani ključ?
Zamislimo da smo zaključali svoje Karta po svakom KnjigaGodina izdanja:
javna karta listToMapWithDupKeyError (Popis knjiga) {return books.stream (). collect (Collectors.toMap (Book :: getReleaseYear, Function.identity ())); }
S obzirom na naš raniji popis knjiga, vidjeli bismo IllegalStateException:
@Test (očekuje se = IllegalStateException.class) javna praznina kada jeMapHasDuplicateKey_without_merge_function_then_runtime_exception () {convertToMap.listToMapWithDupKeyError (bookList); }
Da bismo ga riješili, trebamo upotrijebiti drugu metodu s dodatnim parametrom, spajanjeFunkcija:
Kolektor toMap (Funkcijski keyMapper, Funkcija valueMapper, BinaryOperator mergeFunction)
Uvedimo funkciju spajanja koja ukazuje da u slučaju sudara zadržavamo postojeći unos:
javna karta listToMapWithDupKey (Popis knjiga) {return books.stream (). collect (Collectors.toMap (Book :: getReleaseYear, Function.identity (), (postojeće, zamjena) -> postojeće)); }
Ili, drugim riječima, postižemo ponašanje prve pobjede:
@Test public void whenMapHasDuplicateKeyThenMergeFunctionHandlesCollision () {Map booksByYear = convertToMap.listToMapWithDupKey (bookList); assertEquals (2, booksByYear.size ()); assertEquals ("0395489318", booksByYear.get (1954) .getIsbn ()); }
4. Ostale vrste karte
Prema zadanim postavkama a toMap () metoda će vratiti a HashMap.
Ali možemo li se vratiti različiti Karta implementacije? Odgovor je da:
Kolektor toMap (Funkcijski keyMapper, Funkcija valueMapper, BinaryOperator mergeFunction, Dobavljač mapSupplier)
Gdje je mapDobavljač je funkcija koja vraća novu, praznu Karta s rezultatima.
4.1. Popis do Istodobna karta
Uzmimo isti primjer kao gore i dodajte a mapDobavljač funkcija za povratak a ConcurrentHashMap:
javna karta listToConcurrentMap (Popis knjiga) {return books.stream (). collect (Collectors.toMap (Book :: getReleaseYear, Function.identity (), (o1, o2) -> o1, ConcurrentHashMap :: new)); }
Idemo dalje i testirajte naš kôd:
@Test public void whenCreateConcurrentHashMap () {assertTrue (convertToMap.listToConcurrentMap (bookList) instanceof ConcurrentHashMap); }
Na kraju, pogledajmo kako vratiti sortiranu kartu. Za to ćemo koristiti TreeMap kao mapDobavljač parametar.
Jer a TreeMap je sortirano prema prirodnom redoslijedu ključeva prema zadanim postavkama, ne moramo eksplicitno sortirati knjige sebe:
javna TreeMap listToSortedMap (Popis knjiga) {return books.stream () .collect (Collectors.toMap (Book :: getName, Function.identity (), (o1, o2) -> o1, TreeMap :: new)); }
Dakle, u našem slučaju, vraćeni TreeMap bit će poredano po abecednom redu po nazivu knjige:
@Test public void whenMapisSorted () {assertTrue (convertToMap.listToSortedMap (bookList) .firstKey (). Jednako ("Družina prstena")); }
U ovom smo članku pogledali toMap () metoda Kolekcionari razred. Omogućuje nam stvaranje novog Karta od Stream. Također smo naučili kako riješiti ključne sukobe i stvoriti različite implementacije mapa.
Kao i uvijek kod je dostupan na GitHub-u.