将列表转换为地图 - foreach或stream?

时间:2017-07-06 09:14:54

标签: java java-8 java-stream

我想将List<String>转换为Map<String, Integer>。列表&#39;值应作为键,地图值将静态初始化。

我想保留列表的顺序,因此使用LinkedHashMap,并忽略重复项。

问题:使用java8 stream API有什么好处吗?因为,比较以下内容,仅仅考虑语法,我永远不会使用详细的流api,而是始终坚持使用旧的foreach循环:

    //foreach
    Map<String, Integer> map = new LinkedHashMap<>();
    for (String k : abk) {
        if (k != null) map.put(k, STATIC_VAL);
    }

    //streams
    Map<String, Integer> map2 = abk.stream()
            .filter(Objects::nonNull)
            .collect(Collectors.toMap(
                        Function.identity(),
                        k -> STATIC_VAL,
                        (v1, v2) -> v1,
                        LinkedHashMap::new));

你会坚持使用旧方法还是使用新的lambda表达式?

3 个答案:

答案 0 :(得分:7)

对于这个简单的情况会坚持使用for循环。顺便说一句,它也更快(除了更具可读性),Stream确实需要使用基础设施的成本。这个新API只是一个工具,因为每个工具都有优点/缺点。

一般来说,我只是在必须使用流api时 - 让我们说List需要过滤或映射到其他东西等等 - 然后Stream使用才有意义。如果有多个操作需要完成,那么使代码更容易阅读,然后用循环做同样的事情;但事情并非总是如此 - 如你的例子所示。

并行化(如果你真的需要它是另一个方面)。简单的for循环不容易并行化,但对于流,这是一件轻而易举的事。

答案 1 :(得分:3)

您可以使用传统for循环的变体:

Map<String, Integer> map = new LinkedHashMap<>();
abk.forEach(k -> if (k != null) map.put(k, STATIC_VAL));

但这仅仅是一种风格问题。这种方式或传统的for循环对我来说都很好。另一方面,使用流更简洁,更不易读,IMO。

答案 2 :(得分:2)

您可以使用流编写for-each。例如

abk.stream()
    .filter(Object::notNull)
    .forEach(s->map.put(s, STATIC_VAL));