Reputation: 53806
Below code converts List of Strings where the key and value are separated by "." to type Map<String, java.util.List<String>>
public static void main(String args[]) {
java.util.List<String> l = new java.util.ArrayList<String>();
l.add("key1.value1");
l.add("key1.value2");
l.add("key2.value3");
java.util.Map<String, java.util.List<String>> map = new java.util.HashMap<String, java.util.List<String>>();
l.forEach(line -> {
String[] sa = line.split("\\.");
List<String> ls = map.get(sa[0]);
if (ls == null) {
List<String> initial = new ArrayList<String>();
initial.add(sa[1]);
map.put(sa[0], initial);
} else {
ls.add(sa[1]);
}
});
for (Entry<String, List<String>> entry : map.entrySet()) {
String key = entry.getKey();
List<String> value = entry.getValue();
System.out.println(key+","+StringUtils.join(value , ","));
}
}
Is there a better approach using java lambdas ? Possibly using map function ?
Note : StringUtils is part of commons-lang lib :
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
Upvotes: 2
Views: 681
Reputation: 100199
The correct stream version should use the groupingBy
collector:
Map<String, List<String>> map = l.stream().map(s -> s.split("\\."))
.map(s -> s.length > 1 ? s : new String[] {s[0], ""})
.collect(
Collectors.groupingBy(s -> s[0],
Collectors.mapping(s -> s[1],
Collectors.toList())));
Also note that in Java-8 there's String.join
method, so you don't need the StringUtils
to print the result:
map.entrySet().stream()
.map(e -> e.getKey()+","+String.join(",", e.getValue()))
.forEach(System.out::println);
Upvotes: 5
Reputation: 28026
You can do this:
l.stream()
.map(s -> s.split("\\."))
.collect(Collectors.toMap(s -> s[0], s -> s[1], (a, b) -> b));
The last function is a merge-function which tells it to just pick the last value if two keys are equal. Not providing this function will throw an IllegalStateException
if there are duplicate keys.
If you need a map from Strings to a list of Strings with the same keys. You can use the Collectors.groupingBy
method (as in Tagir Valeev's answer).
Upvotes: 3