关于hashmap:Java 8流:迭代列表地图

Java 8 streams: iterate over Map of Lists

我有以下对象和地图:

1
2
3
4
5
6
MyObject
    String name;
    Long priority;
    foo bar;

Map<String, List<MyObject>> anotherHashMap;

我想在另一个地图中转换地图。 结果映射的键是输入映射的键。 结果映射的值是My对象的Property"name",按优先级排序。

排序和提取名称不是问题,但我无法将其放入结果图中。 我是用旧的Java 7方式做的,但是可以使用流式API是很好的。

1
2
3
4
5
6
Map<String, List<String>> result = new HashMap<>();
for (String identifier : anotherHashMap.keySet()) {
    List<String> generatedList = anotherHashMap.get(identifier).stream()...;

    teaserPerPage.put(identifier, generatedList);
}

有人有想法吗? 我试过这个,但卡住了:

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


1
2
3
4
5
6
7
8
9
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,对其进行排序和应用映射和集合功能。 在这种情况下,我使用MyObject::getName作为映射,并将结果名称收集到列表中。


1
2
3
4
5
6
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进行排序。


为了生成另一个地图,我们可以使用以下内容:

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

上面我再次重新创建地图,但您可以根据需要处理密钥或值。