从地图列表中创建地图 [英] Create a map from a list of maps
问题描述
列表< Map< Integer,String>>
列表中的值是,例如
< 1,String1>
< 2,String2>
< 1,String3>
< 2,String4>
作为最终结果,我想要一个Map>,就像
< 1,< String1,String3>>
<2,< String2,String4>>
如何在Java中实现此功能。
CODE:
List< Map< Integer,String>> genericList = new ArrayList< Map< Integer,String>>(); (TrackActivity activity:activityMajor)
。
{
Map< Integer,String> mapIdResponse = activity.getMapIdResponse();
genericList.add(mapIdResponse);
$ b现在这个泛型列表是输入,并从这个列表中,基于相同的ID我想要一个
Map< Integer,List< String>> mapIdResponseList
基本上,为了将基于id的String响应分组,使用相同的id在列表中,然后创建一个新的地图,该地图的ID为该键,列表为值。
解决方案对于Java 8来说它如下:
private void init(){
List< Map< Integer,String>>> ; mapList = new ArrayList<>();
映射< Integer,String> map1 = new HashMap<>();
map1.put(1,String1);
mapList.add(map1);
映射< Integer,String> map2 = new HashMap<>();
map2.put(2,String2);
mapList.add(map2);
映射< Integer,String> map3 = new HashMap<>();
map3.put(1,String3);
mapList.add(map3);
映射< Integer,String> map4 = new HashMap<>();
map4.put(2,String4);
mapList.add(map4);
Map< Integer,List< String>>响应= 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]
解释(严重担保),恐怕我无法解释每一个细节,您需要了解
Stream
的基本知识。和Collectors
首先在Java 8中引入的API:
- 获取<$ c $从
中输入流<映射<整数,字符串>>mapList
。
Stream< Map.Entry< Integer,String>>>
并将它们添加到现有流中,因此现在它也是类型 Stream< Map.Entry< Integer,String>>
。 Stream< Map。条目< Integer,Str < / code>>< code>映射<整数,列表< String>>
。我将使用一个 Collectors.groupingBy
,它会根据a 将 Map.Entry< Integer,String>
映射到一个函数 Function
整数
在这种情况下。
Map.Entry :: getKey
,它在 Map.Entry
上运行,并返回一个整数
。 Map< Integer,List< Map.Entry< Integer,String>>>
没有做任何额外的处理。 Collectors.groupingBy
添加一个下游,它必须提供一个收集器。 Map.Entry
条目映射到它们的 S饰ng
值通过引用 Map.Entry :: getValue
。 Collectors.toList()
这里,因为我想将它们添加到列表中。 Map<整数,列表,字符串>>
。
I have a list of maps.
List<Map<Integer, String>>
The values in the list are, for example
<1, String1>
<2, String2>
<1, String3>
<2, String4>
As an end result, I want a Map>, like
<1, <String1, String3>>
<2, <String2, String4>>
How can I achieve this in Java.
CODE :
List<Map<Integer, String>> genericList = new ArrayList<Map<Integer,String>>();
for(TrackActivity activity : activityMajor){
Map<Integer, String> mapIdResponse = activity.getMapIdResponse();
genericList.add(mapIdResponse);
}
Now this genericList is the input and from this list, based on the same ids I want a
Map<Integer, List<String>> mapIdResponseList
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.
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);
});
}
This will print:
Integer: 1 / List: [String1, String3]
Integer: 2 / List: [String2, String4]
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:
- 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>>
.
这篇关于从地图列表中创建地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!