10

I'd like to convert a Map <String, Integer> from List<String> in java 8 something like this:

Map<String, Integer> namesMap = names.stream().collect(Collectors.toMap(name -> name, 0));

because I have a list of Strings, and I'd like to to create a Map, where the key is the string of the list, and the value is Integer (a zero).

My goal is, to counting the elements of String list (later in my code).

I know it is easy to convert it, in the "old" way;

Map<String,Integer> namesMap = new HasMap<>();
for(String str: names) {
  map1.put(str, 0);
}

but I'm wondering there is a Java 8 solution as well.

2
  • 9
    Just change 0 to name -> 0: Map<String, Integer> namesMap = names.stream().collect(Collectors.toMap(name -> name, name -> 0)); but this will fail if you have duplicates. If you want to count occurrences, do it right in the first place: Map<String, Long> namesMap = names.stream().collect(Collectors.groupingBy(name -> name, Collectors.counting())); Instead of name -> name, you can also use Function.identity(). Commented Feb 27, 2017 at 13:25
  • Ohh it is working, thank you! :) Commented Feb 27, 2017 at 13:26

2 Answers 2

21

As already noted, the parameters to Collectors.toMap have to be functions, so you have to change 0 to name -> 0 (you can use any other parameter name instead of name).

Note, however, that this will fail if there are duplicates in names, as that will result in duplicate keys in the resulting map. To fix this, you could pipe the stream through Stream.distinct first:

Map<String, Integer> namesMap = names.stream().distinct()
                                     .collect(Collectors.toMap(s -> s, s -> 0));

Or don't initialize those defaults at all, and use getOrDefault or computeIfAbsent instead:

int x = namesMap.getOrDefault(someName, 0);
int y = namesMap.computeIfAbsent(someName, s -> 0);

Or, if you want to get the counts of the names, you can just use Collectors.groupingBy and Collectors.counting:

Map<String, Long> counts = names.stream().collect(
        Collectors.groupingBy(s -> s, Collectors.counting()));
Sign up to request clarification or add additional context in comments.

Comments

9

the toMap collector receives two mappers - one for the key and one for the value. The key mapper could just return the value from the list (i.e., either name -> name like you currently have, or just use the builtin Function.Identity). The value mapper should just return the hard-coded value of 0 for any key:

namesMap = 
    names.stream().collect(Collectors.toMap(Function.identity(), name -> 0));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.