I have a List<String>
and I have to convert it to Map
, by grouping same length String
s into a List
, using String
length as the key in, sorted order. It can be done using -
Map<Integer, List<String>> result = new TreeMap<>();
for (String str : list) {
if (!result.containsKey(str.length())) {
result.put(str.length(), new ArrayList<>());
}
result.get(str.length()).add(str);
}
How can we do it using Java 8 streams?
You could do it with streams:
Map<Integer, List<String>> result = list.stream()
.collect(Collectors.groupingBy(
String::length, // use length of string as key
TreeMap::new, // create a TreeMap
Collectors.toList())); // the values is a list of strings
This collects the stream by means of the overload of Collectors.groupingBy
that accepts 3 arguments: the key mapper function, the supplier of the map and the downstream collector.
However, there's a more compact way to do it, without streams:
Map<Integer, List<String>> result = new TreeMap<>();
list.forEach(s -> result.computeIfAbsent(s.length(), k -> new ArrayList<>()).add(s));
This uses List.forEach
and Map.computeIfAbsent
to achieve what you want.
Java streams can be grouped into a map by using the grouping collectors, the easiest way to make one is to use
Collectors.groupBy(comparator)
where comparator converts streamed values into map keys.
The return is a Map from comparator key to list of entries
public class Test {
public static void main(final String... args) {
List<String> in = Arrays.asList("A", "AB", "B", "ABC");
final Map<Integer, List<String>> all = in.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println(all);
}
}
Output:
{1=[A, B], 2=[AB], 3=[ABC]}
You can do this in Java 8 with groupingBy on one line.
result = list.stream().collect(Collectors.groupingBy(String::length));