下面的代码转换字符串列表,其中键和值由&#34;分隔。&#34;输入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 , ","));
}
}
使用java lambdas有更好的方法吗?可能使用地图功能?
注意:StringUtils是commons-lang lib的一部分:
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
答案 0 :(得分:5)
正确的流版本应使用groupingBy
收集器:
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())));
另请注意,在Java-8中有String.join
方法,因此您不需要StringUtils
来打印结果:
map.entrySet().stream()
.map(e -> e.getKey()+","+String.join(",", e.getValue()))
.forEach(System.out::println);
答案 1 :(得分:3)
你可以这样做:
l.stream()
.map(s -> s.split("\\."))
.collect(Collectors.toMap(s -> s[0], s -> s[1], (a, b) -> b));
最后一个函数是一个merge-function,它告诉它只要两个键相等就选择最后一个值。如果有重复的密钥,则不提供此功能将抛出IllegalStateException
。
如果您需要从字符串到具有相同键的字符串列表的映射。您可以使用Collectors.groupingBy
方法(如Tagir Valeev的答案)。