问题描述
我有一张地图列表.
List<Map<Integer, String>>
列表中的值是,例如
<1, String1>
<2, String2>
<1, String3>
<2, String4>
作为最终结果,我想要一张地图>,比如
As an end result, I want a Map>, like
<1, <String1, String3>>
<2, <String2, String4>>
如何在 Java 中实现这一点.
How can I achieve this in Java.
代码:
List<Map<Integer, String>> genericList = new ArrayList<Map<Integer,String>>();
for(TrackActivity activity : activityMajor){
Map<Integer, String> mapIdResponse = activity.getMapIdResponse();
genericList.add(mapIdResponse);
}
现在这个 genericList 是输入,来自这个列表,基于我想要的相同 id
Now this genericList is the input and from this list, based on the same ids I want a
Map<Integer, List<String>> mapIdResponseList
基本上,将基于 id 的 String 响应组合在一起,将具有相同 id 的响应分组到一个列表中,然后创建一个以该 id 作为键和列表作为其值的新映射.
Basically, to club the responses which are String based on the ids, grouping the responses with same id in a list and then creating a new map with that id as the key and the list as its value.
推荐答案
您可以使用 Java 8 执行以下操作:
You can do it the following with Java 8:
private void init() {
List<Map<Integer, String>> mapList = new ArrayList<>();
Map<Integer, String> map1 = new HashMap<>();
map1.put(1, "String1");
mapList.add(map1);
Map<Integer, String> map2 = new HashMap<>();
map2.put(2, "String2");
mapList.add(map2);
Map<Integer, String> map3 = new HashMap<>();
map3.put(1, "String3");
mapList.add(map3);
Map<Integer, String> map4 = new HashMap<>();
map4.put(2, "String4");
mapList.add(map4);
Map<Integer, List<String>> response = mapList.stream()
.flatMap(map -> map.entrySet().stream())
.collect(
Collectors.groupingBy(
Map.Entry::getKey,
Collectors.mapping(
Map.Entry::getValue,
Collectors.toList()
)
)
);
response.forEach((i, l) -> {
System.out.println("Integer: " + i + " / List: " + l);
});
}
这将打印:
整数:1/列表:[String1, String3]
整数:2/列表:[String2, String4]
Integer: 1 / List: [String1, String3]
Integer: 2 / List: [String2, String4]
解释(非常有根据),恐怕我无法解释每一个细节,您需要先了解Java 8中引入的Stream
和Collectors
API的基础知识:
Explanation (heavily warranted), I am afraid I cannot explain every single detail, you need to understand the basics of the Stream
and Collectors
API introduced in Java 8 first:
- 从
mapList
中获取一个Stream
. - 应用
flatMap
运算符,它将流大致映射到现有流.
这里:我将所有Map
转换为Stream
并将它们添加到现有流中,因此现在是也是> Stream
类型的.> - 我打算将
Stream<Map.Entry<Integer, String>>
收集到一个Map
中. - 为此,我将使用
Collectors.groupingBy
,它基于分组函数生成Map
,> 在这种情况下,将
.Map.Entry
映射到Integer
的函数 - 为此,我使用了一个方法引用,它完全符合我的要求,即
Map.Entry::getKey
,它对Map.Entry
进行操作并返回一个整数
. - 如果我没有做任何额外的处理,此时我将有一个
Map
. - 为了确保我得到正确的签名,我必须向
Collectors.groupingBy
添加一个下游,它必须提供一个收集器. - 对于这个下游,我使用了一个收集器,它通过参考
Map.Entry::getValue
Map.Entry 条目映射到它们的String
值>. - 我还需要指定它们是如何被收集的,这里只是一个
Collectors.toList()
,因为我想将它们添加到一个列表中. - 这就是我们获得
Map<Integer, List,String>>
的方式.
- Obtain a
Stream<Map<Integer, String>>
from themapList
. - Apply the
flatMap
operator, which roughly maps a stream into an already existing stream.
Here: I convert allMap<Integer, String>
toStream<Map.Entry<Integer, String>>
and add them to the existing stream, thus now it is also of typeStream<Map.Entry<Integer, String>>
. - I intend to collect the
Stream<Map.Entry<Integer, String>>
into aMap<Integer, List<String>>
. - For this I will use a
Collectors.groupingBy
, which produces aMap<K, List<V>>
based on a grouping function, aFunction
that maps theMap.Entry<Integer, String>
to anInteger
in this case. - For this I use a method reference, which exactly does what I want, namely
Map.Entry::getKey
, it operates on aMap.Entry
and returns anInteger
. - At this point I would have had a
Map<Integer, List<Map.Entry<Integer, String>>>
if I had not done any extra processing. - To ensure that I get the correct signature, I must add a downstream to the
Collectors.groupingBy
, which has to provide a collector. - For this downstream I use a collector that maps my
Map.Entry
entries to theirString
values via the referenceMap.Entry::getValue
. - I also need to specify how they are being collected, which is just a
Collectors.toList()
here, as I want to add them to a list. - And this is how we get a
Map<Integer, List,String>>
.
这篇关于从地图列表创建地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!