Introduction

Introduced in Java 8, collectors are final classes in Java that extend object classes. The class offers methods for reducing elements in collections based on various rules and criteria. Java collectors provide a static toMap method for producing new Map instances through the collector.

The keys in that newly created Map help calculate the values by applying provided mapping functions. Any repeating key would cause an IllegalStateException every time we try to execute a collection operation. Java Collectors toMap helps convert data structures (a list or an array) into maps by traversing all the elements of a list or array into a newly created Map.

Syntax

toMap(Function keyMapper, Function valueMapper)

Here,

keyMapper: A key-producing or key-returning mapping function.

valueMapper: A value-producing mapping function.

Example

import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.*;

public class Sample {
    public static void main(String[] args) {

        Stream<String[]>
        strm = Stream
        .of(new String[][] { { "ABC", "Sample" }, { "X", "Board" },
            { "Y", "Infinity" }
        });

        Map<String, String>
        map_sample = strm.collect(
                  Collectors.toMap(p -> p[0], p -> p[1]));

        System.out.println("Map:" + map_sample);
    }
}



Output
Map:{ABC=Sample, X=Board, Y=Infinity}

Collectors.toMap() with Mapper Functions

There are only two mapper functions required - a keyMapper and a valueMapper:

public static <T,K,U> Collector<T,?,Map<K,U>>
    toMap(Function<? super T,? extends K> keyMapper,
          Function<? super T,? extends U> valueMapper)

The keyMapper function outputs the key of the final Map.

ValueMapper returns the values of the final Map as its output.

The method returns a Collector, which collects elements into a Map, whose pair <K, V> represents the mapping functions previously applied.

Collectors.toMap() with Mapper and Merge Functions

We can also provide a Merge Function in addition to the two Mapper Functions:

public static <T,K,U> Collector<T,?,Map<K,U>>
    toMap(Function<? super T,? extends K> keyMapper,
          Function<? super T,? extends U> valueMapper,
          BinaryOperator<U> mergeFunction)

Whenever there is a duplicate key element in the final Map, the mergeFunction gets called to merge their values and assign them to one unique key.

It takes two input values, i.e., the two keyMapper returned values, and combines them into one value.

Collectors.toMap() with Mapper, Merge, and Supplier Functions.

Developers can specify a Supplier function in the final overloaded version of the method - to implement a new Map interface for "packing in the result":

public static <T,K,U,M extends Map<K,U>> Collector<T,?,M>
    toMap(Function<? super T,? extends K> keyMapper,
          Function<? super T,? extends U> valueMapper,
          BinaryOperator<U> mergeFunction,
          Supplier<M> mapSupplier)

It specifies which implementation of Map we want to use for our final Map in the mapSupplier function. As a default, Java uses a HashMap to store the maps when we use Map to declare them.

Code Sample

The following code will help you understand how to use Collector Tomap() method in java.

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class CollectorsToMapSample {

public static void main(String[] args) {
List<String> numbtoStrList = new ArrayList<>();

numbtoStrList.add("Six");
numbtoStrList.add("Seven");
numbtoStrList.add("Three");
numbtoStrList.add("Two");
numbtoStrList.add("Five");

Map<String, Integer> map_sample = numbtoStrList.stream()
.collect(Collectors.toMap(Function.identity(), String::length));
System.out.println("List : "+numbtoStrList);
System.out.println("Map : "+map_sample);

}

}



Output
List : [Six, Seven, Three, Two, Five]
Map : {Five=4, Six=3, Seven=5, Two=3, Three=5}