If your ending map has a chance of "duplicate keys", there is a better solution using

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

You could use it like this:

HashMap<Set<Integer>, Double> map = container.entrySet()
    .stream()
    .filter(k -> k.getKey().size() == size)
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (prev, next) -> next, HashMap::new));

Then as duplicate keys are added, it will use the latest instead of throwing an exception. The last parameter is optional.

If you want to keep duplicate keys into a list, then use Collectors.groupingBy instead.

Answer from provisota on Stack Overflow
🌐
Baeldung
baeldung.com › home › java › java collections › java map › working with maps using streams
Working With Maps Using Streams | Baeldung
November 10, 2025 - Learn how to use the toMap() method of the Collectors class. ... The article is an example-heavy introduction of the possibilities and operations offered by the Java 8 Stream API.
Discussions

Hashmap with Streams in Java 8 Streams to collect value of Map - Stack Overflow
Let consider a hashmap Map id1 = new HashMap (); I inserted some values into both hashmap. For Example, List list1 = new ArrayList More on stackoverflow.com
🌐 stackoverflow.com
java - Java8: HashMap to HashMap using Stream / Map-Reduce / Collector - Stack Overflow
220 In Java 8 how do I transform a Map to another Map using a lambda? 60 Collect stream into a HashMap with Lambda in Java 8 More on stackoverflow.com
🌐 stackoverflow.com
How to convert Array to HashMap using Java 8 Stream - Stack Overflow
If you want to have a guaranty ... key");}, HashMap::new) instead. ... Sign up to request clarification or add additional context in comments. ... Getting exactly what you want will probably not work for maps whose key type differs from their value type. This is because Java's variable ... More on stackoverflow.com
🌐 stackoverflow.com
Java 8 streams - String to HashMap counter of characters
CharSequence.chars() gives you an IntStream whose collect(...) method isn't compatible with Collectors.groupingBy(...)). However you should be able to .mapToObj(c -> c) before the collect to get a Stream that can be collected that way (at the expense of what could be a lot of boxing). More on reddit.com
🌐 r/learnjava
1
1
August 22, 2018
🌐
HowToDoInJava
howtodoinjava.com › home › java 8 › java collectors.tomap(): collecting stream items into map
Java Collectors.toMap(): Collecting Stream Items into Map
October 14, 2023 - Learn to collect Stream items into Map using Collectors.toMap() and Collectors.groupingBy() when Map keys are distinct or duplicates.
🌐
Baeldung
baeldung.com › home › java › java collections › java map › convert a stream into a map or multimap in java
Convert a Stream into a Map or Multimap in Java | Baeldung
December 26, 2023 - Explore ways of transforming a stream into a Map or Multimap in Java using various approaches and libraries.
🌐
GeeksforGeeks
geeksforgeeks.org › java › how-to-convert-a-stream-into-a-map-in-java
How to convert a Stream into a Map in Java - GeeksforGeeks
July 15, 2025 - ValueMapper: This function used for extracting the values of the map for the given key. The following are the examples of the toMap function to convert the given stream into a map:
🌐
Benchresources
benchresources.net › home › java › java 8 – convert stream to hashmap
Java 8 - Convert Stream to HashMap - BenchResources.Net
June 3, 2022 - Stream of String tokens Stream<String> nameStream = Stream.of( "Rajiv", "Anbu", "Santosh", "Abdul", "Lingaraj" ); // 2. convert Stream<String> to HashMap<String, Integer> HashMap<String, Integer> hMap = nameStream .collect(Collectors.toMap( Function.identity(), // 1. actual String as KEY String::length, // 2. String length as their VALUE (key1, key2) -> key1, // 3. duplicate KEY resolver HashMap::new // 4. implementation-class )); // 2.1 print to console System.out.println("Stream to HashMap conversion : \n\n" + hMap); } } ... https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toMap-java.util.function.Function-java.util.function.Function-
Find elsewhere
🌐
Java67
java67.com › 2019 › 05 › how-to-convert-stream-to-list-set-map-in-java.html
How to Convert a Stream to List, Set, and Map in Java? Example Tutorial | Java67
Our complete Java program demonstrates how you can use the Collectors class to convert a Stream of values into List, Set, Map, and ConcurrentMap in Java. Not only you will learn to convert Stream to generic Collection classes but also specific ones like ArrayList, LinkedList, HashMap, HashSet, LinkedHashMap, and TreeMap.
Top answer
1 of 10
520
Map<String, String> x;
Map<String, Integer> y =
    x.entrySet().stream()
        .collect(Collectors.toMap(
            e -> e.getKey(),
            e -> Integer.parseInt(e.getValue())
        ));

It's not quite as nice as the list code. You can't construct new Map.Entrys in a map() call so the work is mixed into the collect() call.

2 of 10
38

Here are some variations on Sotirios Delimanolis' answer, which was pretty good to begin with (+1). Consider the following:

static <X, Y, Z> Map<X, Z> transform(Map<? extends X, ? extends Y> input,
                                     Function<Y, Z> function) {
    return input.keySet().stream()
        .collect(Collectors.toMap(Function.identity(),
                                  key -> function.apply(input.get(key))));
}

A couple points here. First is the use of wildcards in the generics; this makes the function somewhat more flexible. A wildcard would be necessary if, for example, you wanted the output map to have a key that's a superclass of the input map's key:

Map<String, String> input = new HashMap<String, String>();
input.put("string1", "42");
input.put("string2", "41");
Map<CharSequence, Integer> output = transform(input, Integer::parseInt);

(There is also an example for the map's values, but it's really contrived, and I admit that having the bounded wildcard for Y only helps in edge cases.)

A second point is that instead of running the stream over the input map's entrySet, I ran it over the keySet. This makes the code a little cleaner, I think, at the cost of having to fetch values out of the map instead of from the map entry. Incidentally, I initially had key -> key as the first argument to toMap() and this failed with a type inference error for some reason. Changing it to (X key) -> key worked, as did Function.identity().

Still another variation is as follows:

static <X, Y, Z> Map<X, Z> transform1(Map<? extends X, ? extends Y> input,
                                      Function<Y, Z> function) {
    Map<X, Z> result = new HashMap<>();
    input.forEach((k, v) -> result.put(k, function.apply(v)));
    return result;
}

This uses Map.forEach() instead of streams. This is even simpler, I think, because it dispenses with the collectors, which are somewhat clumsy to use with maps. The reason is that Map.forEach() gives the key and value as separate parameters, whereas the stream has only one value -- and you have to choose whether to use the key or the map entry as that value. On the minus side, this lacks the rich, streamy goodness of the other approaches. :-)

Top answer
1 of 6
15

You may use

public static <K, V> Map<K, V> toMap(Object... entries) {
    if(entries.length % 2 == 1)
        throw new IllegalArgumentException("Invalid entries");
    return (Map<K, V>)IntStream.range(0, entries.length/2).map(i -> i*2)
        .collect(HashMap::new, (m,i)->m.put(entries[i], entries[i+1]), Map::putAll);
}

but it will give you a (founded) unchecked warning. Your method can’t hold the promise to return a correctly typed Map<K, V> for an array of arbitrary objects and, even worse, it will not fail with an exception, but silently return an inconsistent map if you pass in objects of the wrong type.

A cleaner, commonly used, solution is

public static <K, V> Map<K, V> toMap(
                               Class<K> keyType, Class<V> valueType, Object... entries) {
    if(entries.length % 2 == 1)
        throw new IllegalArgumentException("Invalid entries");
    return IntStream.range(0, entries.length/2).map(i -> i*2)
        .collect(HashMap::new,
                 (m,i)->m.put(keyType.cast(entries[i]), valueType.cast(entries[i+1])),
                 Map::putAll);
}

This can be compiled without a warning, as the correctness will be checked at runtime. The calling code has to be adapted:

Map<String, Integer> map1 = toMap(String.class, Integer.class, "k1", 1, "k2", 2);
Map<String, String> map2 = toMap(
                           String.class, String.class, "k1", "v1", "k2", "v2", "k3", "v3");

Besides the need to specify the actual types as class literals, it has the disadvantage of not supporting generic key or value types (as they can’t be expressed as Class) and still having no compile-time safety, only a runtime check.


It’s worth looking at Java 9. There, you will be able to do:

Map<String, Integer> map1 = Map.of("k1", 1, "k2", 2);
Map<String, String>  map2 = Map.of("k1", "v1", "k2", "v2", "k3", "v3");

This will create an immutable map of an unspecified type, rather than a HashMap, but the interesting point is the API.

There is a method <K,V> Map.Entry<K,V> entry(K k, V v) which can be combined with
<K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries) to create a map of a variable length (varargs are still limited to 255 parameters, though).

You can implement a similar thing:

public static <K,V> Map.Entry<K,V> entry(K k, V v) {
    return new AbstractMap.SimpleImmutableEntry<>(k, v);
}
public static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries) {
    return Arrays.stream(entries)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

The convenience method(s) of are implemented the only way, this can be done with type safety: as overloaded methods with different numbers of arguments, like

public static <K,V> Map<K,V> of() {
    return new HashMap<>();// or Collections.emptyMap() to create immutable maps
}
static <K,V> Map<K,V> of(K k1, V v1) {
    return ofEntries(entry(k1, v1));
}
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2) {
    return ofEntries(entry(k1, v1), entry(k2, v2));
}
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
    return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3));
}
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
    return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3), entry(k4, v4));
}   
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
    return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3), entry(k4, v4));
}   

(Java 9 makes the cut at ten mappings, if you have more, you have to use the ofEntries(entry(k1, v1), …) variant).

If you follow this pattern, you should keep your toMap name or use just map, rather than calling at “of”, as you are not writing the Map interface.

These overloads might not look very elegant, but they solve all problems. You can write the code just as in your question, without specifying Class objects, but gain compile-time type safety and even rejection of attempts to call it with an odd number of arguments.

You have to make a cut at a certain number of parameters, but, as already noted, even varargs do not support unlimited parameters. And the ofEntries(entry(…), …) form isn’t so bad for larger maps.


The collector Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue) returns an unspecified map type, which might even be immutable (though it’s a HashMapin the current version). If you want to have a guaranty that a HashMap instance is returned, you have to use Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1,v2)->{throw new IllegalArgumentException("duplicate key");}, HashMap::new) instead.

2 of 6
2

Getting exactly what you want will probably not work for maps whose key type differs from their value type. This is because Java's variable arity declaration (the Object... entries part) supports only one type.

Some options come to mind:

  1. You could do the checks dynamically and throw an illegal argument exception if the values don't match. But you'll lose the compiler type-checking.

  2. You could define a Pair class, and play a bit with static import to get almost what you want:

e.g.:

class Pair<K,V> {
    final K k;
    final V v;
    Pair( K ak, V av) {
        k=ak;
        v=av;
    }
    static <A,B> Pair<A,B> p(A a, B b) {
        return new Pair(a,b);
    }
}

public class JavaTest8 {

    <K,V> Map<K,V> toMap( Pair<K,V>... pairs ) {
        return Arrays.stream(pairs).collect(Collectors.toMap(p->p.k, p->p.v));
    }

    public static void main(String[] args) {
        // Usage
        Map<String,Integer> sti = toMap( p("A",1), p("B",2) );
        Map<Integer,Boolean> itb = toMap( p(1,true), p(42,false) );
    }
}
🌐
Medium
medium.com › @kavya1234 › common-stream-operations-on-hashmap-entries-in-java-6fe29fb5ceed
Common Stream Operations on HashMap Entries in Java | by Kavya | Medium
February 24, 2025 - Java’s Stream API, introduced in Java 8, revolutionized the way developers interact with collections, including HashMap. By leveraging streams, we can perform operations on the entries of a HashMap in a more concise and readable manner. In this blog, we’ll explore various common stream operations on HashMap entries with practical examples and explanations. The Stream API allows us to ...
🌐
Coderanch
coderanch.com › t › 657075 › java › Set-HashMap-Objects-Streams
Set HashMap Objects using Streams (Features new in Java 8 forum at Coderanch)
I have the below code as per the traditional way to iterate and set the object value in hashmap as follows. I don't want to initialize the obj inside stream.
🌐
CodingNConcepts
codingnconcepts.com › java › streams-with-map-java-8
Using Streams API with Map in Java 8 - Coding N Concepts
September 30, 2023 - Java 8 Streams provide Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapFactory) overloaded method where you can specify the type using mapFactory to return ConcurrentHashMap, LinkedHashMap or TreeMap.
🌐
Reddit
reddit.com › r/learnjava › java 8 streams - string to hashmap counter of characters
r/learnjava on Reddit: Java 8 streams - String to HashMap counter of characters
August 22, 2018 -

Given a String, I want to create a hashmap that maps a Character to the number of times it shows up in the string.

I saw in Stack Overflow the following line:

Map<String, Long> map =
    Arrays.stream(s1.split("")).
            collect(Collectors.groupingBy(c -> c, Collectors.counting()));

And it works great, but it maps a String to the counter.

I tried writing it for Characters, and as far as I understood, there isn't a char stream, and I'll have to use IntStream. So I converted it to an IntStream, and used the same Collectors function.

Map<Integer, Long> map =
    s1.chars().
            collect(Collectors.groupingBy(c -> c, Collectors.counting()));

The above doesn't work. The error is:

Error:(14, 27) java: method collect in interface java.util.stream.IntStream cannot be applied to given types;

required: java.util.function.Supplier<R>,java.util.function.ObjIntConsumer<R>,java.util.function.BiConsumer<R,R>

found: java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.Map<java.lang.Object,java.lang.Long>>

reason: cannot infer type-variable(s) R

(actual and formal argument lists differ in length)

What is the difference between the two?

🌐
Medium
medium.com › @lavishj77 › java-8-stream-fa389cd53450
Java 8 Stream. Streams is another major concept… | by Lavish Jain | Medium
July 21, 2022 - Map<Integer, String> map = new HashMap(); Stream<Map.Entry<Integer, String>> stream = map.entrySet().stream(); We can supply the of() method with any number of arguments, and get back an ordered stream of those values.
🌐
Blogger
javarevisited.blogspot.com › 2016 › 04 › 10-examples-of-converting-list-to-map.html
10 Examples of Converting a List to Map in Java 8
In the past, we have seen how to use the Collectors.groupingBy() method to group elements in Set and In this article, we will use Collectors.toMap() method to convert a List of an object into a Map in Java.
🌐
Coderanch
coderanch.com › t › 729178 › java › Count-total-price-items-HashMap
Count total price of items in HashMap via Streams (Features new in Java 8 forum at Coderanch)
If you have the price as a primitive you may be able to get a Stream of primitives with a method called mapToXYZ() and use its sum() method, otherwise you would have to write a Collector with its three parts yourself, or use the reduce() method which you will find examples of in the package ...
🌐
Mkyong
mkyong.com › home › java8 › java 8 map filter examples
Java 8 Map filter examples - Mkyong.com
March 13, 2024 - package com.mkyong.examples; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class MapFilterExample2 { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "linode"); map.put(2, "heroku"); map.put(3, "aws"); //Map -> Stream -> Filter -> String String result1 = map.values().stream() .filter("linode"::equals) .collect(Collectors.joining()); // linode System.out.println(result1); //Map -> Stream -> Filter -> MAP Map<Integer, String> result2 = map.entrySet().stream() .filter(x -> x.getKey() == 1) .collect(Collect
🌐
Baeldung
baeldung.com › home › java › java collections › java map › java collectors tomap
Java Collectors toMap | Baeldung
February 26, 2026 - We’ll use it to collect Streams into a Map instance. For all the examples covered here, we’ll use a list of books as a starting point and transform it into different Map implementations. The article discusses Java 8 Collectors, showing examples of built-in collectors, as well as showing how to build custom collector.