Java 8 Collectors toMap

1. Introduksjon

I denne raske opplæringen skal vi snakke om å kartlegge() metoden for Samlere klasse. Vi bruker den til å samle inn Strøms inn i en Kart forekomst.

For alle eksemplene som er dekket her, bruker vi en liste over bøker som utgangspunkt og forvandler den til forskjellige Kart implementeringer.

2. Liste til Kart

Vi begynner med det enkleste tilfellet ved å transformere a Liste inn i en Kart.

Våre Bok klasse er definert som:

class Book {private String name; privat int release År; private String isbn; // getters og setters}

Og vi lager en liste over bøker for å validere koden vår:

Liste bookList = ny ArrayList (); bookList.add (ny bok ("The Fellowship of the Ring", 1954, "0395489318")); bookList.add (ny bok ("De to tårnene", 1954, "0345339711")); bookList.add (ny bok ("The Return of the King", 1955, "0618129111"));

For dette scenariet bruker vi følgende overbelastning av å kartlegge() metode:

Samler toMap (Function keyMapper, Function valueMapper)

Med å kartlegge, kan vi indikere strategier for hvordan du får nøkkelen og verdien til kartet:

public Map listToMap (List books) {return books.stream (). collect (Collectors.toMap (Book :: getIsbn, Book :: getName)); }

Og vi kan enkelt validere at det fungerer med:

@Test offentlig ugyldig nårConvertFromListToMap () {assertTrue (convertToMap.listToMap (bookList) .size () == 3); }

3. Løsning av viktige konflikter

Eksemplet ovenfor fungerte bra, men hva ville skje hvis det er en duplikatnøkkel?

La oss forestille oss at vi tastet inn vår Kart av hver BokUtgivelsesår:

offentlig kartlisteToMapWithDupKeyError (List books) {return books.stream (). collect (Collectors.toMap (Book :: getReleaseYear, Function.identity ())); }

Gitt vår tidligere liste over bøker, ville vi se en IllegalStateException:

@Test (forventet = IllegalStateException.class) offentlig ugyldig når MapHasDuplicateKey_without_merge_function_then_runtime_exception () {convertToMap.listToMapWithDupKeyError (bookList); }

For å løse det, må vi bruke en annen metode med en ekstra parameter, the mergeFunction:

Collector toMap (Function keyMapper, Function valueMapper, BinaryOperator mergeFunction) 

La oss introdusere en flettefunksjon som indikerer at i tilfelle en kollisjon beholder vi den eksisterende oppføringen:

offentlig kartlisteToMapWithDupKey (listebøker) {return books.stream (). collect (Collectors.toMap (Book :: getReleaseYear, Function.identity (), (eksisterende, erstatning) -> eksisterende)); }

Eller med andre ord, vi får først-vinn-oppførsel:

@Test offentlig ugyldig når MapHasDuplicateKeyThenMergeFunctionHandlesCollision () {Map booksByYear = convertToMap.listToMapWithDupKey (bookList); assertEquals (2, booksByYear.size ()); assertEquals ("0395489318", booksByYear.get (1954) .getIsbn ()); }

4. Andre karttyper

Som standard er a å kartlegge() metoden vil returnere a HashMap.

Men kan vi komme tilbake annerledes Kart implementeringer? Svaret er ja:

Collector toMap (Function keyMapper, Function valueMapper, BinaryOperator mergeFunction, Supplier mapSupplier)

Hvor i mapSupplier er en funksjon som returnerer en ny, tom Kart med resultatene.

4.1. Liste til ConcurrentMap

La oss ta det samme eksemplet som ovenfor og legge til en mapSupplier funksjon for å returnere a ConcurrentHashMap:

public Map listToConcurrentMap (List books) {return books.stream (). collect (Collectors.toMap (Book :: getReleaseYear, Function.identity (), (o1, o2) -> o1, ConcurrentHashMap :: new)); }

La oss fortsette og teste koden vår:

@Test offentlig ugyldig nårCreateConcurrentHashMap () {assertTrue (convertToMap.listToConcurrentMap (bookList) instance of ConcurrentHashMap); }
4.2. Sortert Kart

Til slutt, la oss se hvordan du returnerer et sortert kart. For det bruker vi en TreeMap som en mapSupplier parameter.

Fordi en TreeMap sorteres i henhold til den naturlige rekkefølgen på nøklene som standard, trenger vi ikke å eksplisitt sortere bøker oss:

public TreeMap listToSortedMap (List books) {return books.stream () .collect (Collectors.toMap (Book :: getName, Function.identity (), (o1, o2) -> o1, TreeMap :: new)); }

Så i vårt tilfelle returnerte TreeMap vil bli sortert i alfabetisk rekkefølge etter boknavnet:

@Test offentlig ugyldig når MapSSorted () {assertTrue (convertToMap.listToSortedMap (bookList) .firstKey (). Tilsvarer ("The Fellowship of the Ring")); }
5. Konklusjon

I denne artikkelen så vi på å kartlegge() metoden for Samlere klasse. Det lar oss lage et nytt Kart fra en Strøm. Vi lærte også hvordan vi kan løse viktige konflikter og lage forskjellige kartimplementeringer.

Som alltid er koden tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found