使用Lambda Map函数代替迭代来填充Map

时间:2015-08-21 09:33:42

标签: java lambda java-8

下面的代码转换字符串列表,其中键和值由&#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>

2 个答案:

答案 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的答案)。