Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java List<String> to Map<String, Integer> convertion

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.

like image 997
LakiGeri Avatar asked Feb 27 '17 13:02

LakiGeri


People also ask

Can a List be converted to map in Java?

Using Collectors. toMap() method: This method includes creation of a list of the student objects, and uses Collectors. toMap() to convert it into a Map.

How can we convert List to map?

List<Integer> intList = Arrays. asList(1, 2, 3, 4, 5, 6); Map<String, Integer> map = intList. stream(). collect(toMap(i -> String.

Can we convert string to HashMap in Java?

We can also convert an array of String to a HashMap. Suppose we have a string array of the student name and an array of roll numbers, and we want to convert it to HashMap so the roll number becomes the key of the HashMap and the name becomes the value of the HashMap. Note: Both the arrays should be the same size.


2 Answers

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()));
like image 89
tobias_k Avatar answered Sep 22 '22 05:09

tobias_k


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));
like image 40
Mureinik Avatar answered Sep 19 '22 05:09

Mureinik