Java 8 Collectors toMap

1. Introduktion

I denne hurtige vejledning skal vi tale om at kortlægge() metode til Samlere klasse. Vi bruger det til at indsamle Strøms ind i en Kort eksempel.

For alle eksemplerne, der er dækket her, bruger vi en liste over bøger som udgangspunkt og omdanner den til forskellige Kort implementeringer.

2. Liste til Kort

Vi starter med det enkleste tilfælde ved at omdanne en Liste ind i en Kort.

Vores Bestil klasse er defineret som:

klasse Bog {privat strengnavn; privat int release År; privat streng isbn; // getters og setters}

Og vi opretter en liste over bøger for at validere vores kode:

Liste bookList = ny ArrayList (); bookList.add (ny bog ("The Fellowship of the Ring", 1954, "0395489318")); bookList.add (ny bog ("De to tårne", 1954, "0345339711")); bookList.add (ny bog ("Kongens tilbagevenden", 1955, "0618129111"));

I dette scenarie bruger vi følgende overbelastning af at kortlægge() metode:

Samler toMap (Function keyMapper, Function valueMapper)

Med at kortlægge, kan vi indikere strategier for, hvordan man får nøglen og værdien til kortet:

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

Og vi kan nemt validere det fungerer med:

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

3. Løsning af nøglekonflikter

Eksemplet ovenfor fungerede godt, men hvad ville der ske, hvis der er en duplikatnøgle?

Lad os forestille os, at vi indtastede vores Kort af hver Bestil'S udgivelsesår:

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

I betragtning af vores tidligere liste over bøger ville vi se en IllegalStateException:

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

For at løse det skal vi bruge en anden metode med en yderligere parameter, mergeFunction:

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

Lad os introducere en fusionsfunktion, der indikerer, at vi i tilfælde af en kollision beholder den eksisterende post:

public Map listToMapWithDupKey (List books) {return books.stream (). collect (Collectors.toMap (Book :: getReleaseYear, Function.identity (), (eksisterende, erstatning) -> eksisterende)); }

Eller med andre ord får vi førstegangs-opførsel:

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

4. Andre korttyper

Som standard er a at kortlægge() metoden returnerer a HashMap.

Men kan vi vende tilbage anderledes Kort implementeringer? Svaret er ja:

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

Hvor er mapSupplier er en funktion, der returnerer en ny, tom Kort med resultaterne.

4.1. Liste til ConcurrentMap

Lad os tage det samme eksempel som ovenfor og tilføje en mapSupplier funktion til at returnere en ConcurrentHashMap:

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

Lad os fortsætte og teste vores kode:

@Test offentligt ugyldigt nårCreateConcurrentHashMap () {assertTrue (convertToMap.listToConcurrentMap (bookList) instance of ConcurrentHashMap); }
4.2. Sorteret Kort

Lad os endelig se, hvordan du returnerer et sorteret kort. Til det bruger vi en TreeMap som en mapSupplier parameter.

Fordi en TreeMap sorteres efter den naturlige rækkefølge af dens nøgler som standard, behøver vi ikke eksplicit at sortere bøger os selv:

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

Så i vores tilfælde returnerede TreeMap vil blive sorteret i alfabetisk rækkefølge efter bognavnet:

@Test offentligt ugyldigt, når MapSorted () {assertTrue (convertToMap.listToSortedMap (bookList) .firstKey (). Er lig med ("The Fellowship of the Ring")); }
5. Konklusion

I denne artikel kiggede vi på at kortlægge() metode til Samlere klasse. Det giver os mulighed for at skabe et nyt Kort fra en Strøm. Vi lærte også, hvordan man løser nøglekonflikter og opretter forskellige kortimplementeringer.

Som altid er koden tilgængelig på GitHub.