Java 8 流:迭代列表映射

Posted

技术标签:

【中文标题】Java 8 流:迭代列表映射【英文标题】:Java 8 streams: iterate over Map of Lists 【发布时间】:2015-02-11 10:29:24 【问题描述】:

我有以下对象和地图:

MyObject
    String name;
    Long priority;
    foo bar;

Map<String, List<MyObject>> anotherHashMap;

我想将地图转换为另一个地图。结果映射的键是输入映射的键。结果映射的值是我的对象的属性“名称”,按优先级排序。

ordering 和提取名称不是问题,但我无法将其放入结果图中。我用旧的 Java 7 方式来做,但如果可以使用流式 API,那就太好了。

Map<String, List<String>> result = new HashMap<>();
for (String identifier : anotherHashMap.keySet()) 
    List<String> generatedList = anotherHashMap.get(identifier).stream()...;

    teaserPerPage.put(identifier, generatedList);

有人知道吗?我试过了,但卡住了:

anotherHashMap.entrySet().stream().collect(Collectors.asMap(..., ...));

【问题讨论】:

意图不明确。你能解释一下你想做什么吗? 这个解释更好吗? 您生成的地图值应该是多少?前一个密钥中每个 name 的列表? 【参考方案1】:
Map<String, List<String>> result = anotherHashMap
    .entrySet().stream()                    // Stream over entry set
    .collect(Collectors.toMap(              // Collect final result map
        Map.Entry::getKey,                  // Key mapping is the same
        e -> e.getValue().stream()          // Stream over list
            .sorted(Comparator.comparingLong(MyObject::getPriority)) // Sort by priority
            .map(MyObject::getName)         // Apply mapping to MyObject
            .collect(Collectors.toList()))  // Collect mapping into list
        );

本质上,您流过每个条目集并将其收集到新地图中。要计算新映射中的值,您可以从旧映射中流式传输List&lt;MyOjbect&gt;,对其进行排序并应用映射和集合函数。在这种情况下,我使用MyObject::getName 作为映射并将生成的名称收集到一个列表中。

【讨论】:

【参考方案2】:

为了生成另一个地图,我们可以有如下的东西:

HashMap<String, List<String>> result = anotherHashMap.entrySet().stream().collect(Collectors.toMap(elem -> elem.getKey(), elem -> elem.getValue() // can further process it);

上面我在重新创建地图,但是你可以根据自己的需要处理key或者value。

【讨论】:

我相信应该是.stream().collect。您还需要映射MyObject 的列表,例如elem -&gt; elem.getValue().stream().map(e -&gt; e.name) 忘记添加 entrySet().stream() 已修复:)【参考方案3】:
Map<String, List<String>> result = anotherHashMap.entrySet().stream().collect(Collectors.toMap(
    Map.Entry::getKey,
    e -> e.getValue().stream()
        .sorted(comparing(MyObject::getPriority))
        .map(MyObject::getName)
        .collect(Collectors.toList())));

与 Mike Kobit 的回答类似,但排序应用在正确的位置(即对值进行排序,而不是映射条目),并且使用更简洁的静态方法 Comparator.comparing 来获取 Comparator 进行排序。

【讨论】:

以上是关于Java 8 流:迭代列表映射的主要内容,如果未能解决你的问题,请参考以下文章

从 java 8 流中的列表中过滤值

java 具有多个对象流的列表:在此示例中,将列值,titleValue和titleSortValue赋予列表。在迭代l

使用java 8迭代和过滤两个列表

Java 8 流不可预测的性能下降,没有明显的原因

Java 8 流映射到按值排序的键列表

如何使用 lambda 流迭代嵌套列表?