java 8 将具有相同键和值的映射分组并组成键值对
java 8 grouping a map of same key and value and make a key value pair
我有一个方法 fetchConfigsCount()
returns List<Map<String, Object>>
。
结果如下:
{
"web_id": "abc",
"count": 1
},
{
"web_id": "xyz",
"count": 1
},
{
"web_id": "pqr",
"count": 1
}
我们有另一种方法 fetchWebsitesCount()
,它也 returns 一个相同格式的响应。
web_id
是键,其值为所有者名称。
count
是另一个键,它的值是 int
.
类型
{
"web_id": "abc",
"count": 2
},
{
"web_id": "xyz",
"count": 3
},
{
"web_id": "pqr",
"count": 4
}
我们有一个类型为 ArrayList<String>
:
的所有者列表
List<String> listOfOwners = ["abc","xyz","pqr"];
我想收集所有这些东西并想创建如下结果:
result:[
{"owner": "abc",
"ownerPresence":{
"configCount":1,
"websiteCount":2
},
{"owner": "xyz",
"ownerPresence":{
"configCount":1,
"websiteCount":3
},
{"owner": "pqr",
"ownerPresence":{
"configCount":1,
"websiteCount":4
}]
我不确定如何在 Java 8 中做到这一点。
- 将初始地图列表重新映射到
Map<String, Integer>
:
static Map<String, Integer> convert(List<Map<String, Object>> list) {
return list
.stream()
.collect(Collectors.toMap(
m -> (String) m.get("web_id"),
m -> (Integer) m.get("count")
));
}
List<Map<String, Object>> configs = fetchConfigsCount();
List<Map<String, Object>> websites = fetchWebsitesCount();
Map<String, Integer> configMap = convert(configs);
Map<String, Integer> websiteMap = convert(websites);
- 创建一个 POJO 来表示列表条目:
class Pojo {
String owner;
Map<String, Integer> ownerPresence;
// boilerplate: constructor(s), getters/setters
}
- 流式传输所有者列表,并构建地图:
List<String> listOfOwners = Arrays.asList("abc","xyz","pqr");
List<Pojo> result = listOfOwners
.stream()
.map(owner -> new Pojo(
owner,
Map.of(
"configCount", configMap.get(owner),
"websiteCount", websiteMap.get(owner)
)
))
.collect(Collectors.toList());
更新
如果有其他输入,可以创建包装器映射以通过适当的键 "configCount", "websiteCount", "sourceCount"
等保存转换后的映射:
Map<String, Map<String, Integer>> bigMap = Map.of(
"configCount", convert(fetchConfigsCount()),
"websiteCount", convert(fetchWebsitesCount()),
"sourceCount", convert(fetchSourcesCount())
);
然后 Pojo
的地图可以这样创建:
List<Pojo> result = listOfOwners
.stream()
.map(owner -> new Pojo(
owner,
bigMap.keySet()
.stream() // Stream<String>
.collect(Collectors.toMap(
k -> k,
k -> bigMap.get(k).get(owner)
)) // Map<String, Integer>
))
.collect(Collectors.toList());
这是一种方法。
- 首先,只需将计数重新映射到
Map<String,List<Integer>>
- 然后简单地迭代 map,构建最终的 map 和列表。
List<Map<String, Object>> configCount =
List.of(Map.of("web_id", "abc", "count", 1),
Map.of("web_id", "xyz", "count", 1),
Map.of("web_id", "pqr", "count", 1));
List<Map<String, Object>> webCount =
List.of(Map.of("web_id", "abc", "count", 2),
Map.of("web_id", "xyz", "count", 3),
Map.of("web_id", "pqr", "count", 4));
List<Map<String, Object>> sourceCount =
List.of(Map.of("web_id", "abc", "count", 22),
Map.of("web_id", "xyz", "count", 32),
Map.of("web_id", "pqr", "count", 42));
Map<String, List<Integer>> map = Stream
.concat(configCount.stream(),
Stream.concat(webCount.stream(),
sourceCount.stream()))
.collect(Collectors.groupingBy(
mp -> (String) mp.get("web_id"),
Collectors.mapping(
mp -> (Integer) mp.get("count"),
Collectors.toList())));
上面创建了以下内容,其中第一个 List
值按顺序为“配置、网站和来源”。
pqr=[1, 4, 42]
abc=[1, 2, 22]
xyz=[1, 3, 32]
现在实例化一个最终列表来保存所有地图并完成。
List<Map<String, Object>> result = new ArrayList<>();
for (Entry<String, List<Integer>> e : map.entrySet()) {
Map<String, Object> tempMap = new HashMap<>();
tempMap.put("owner", e.getKey());
tempMap.put("ownerPresence",
new HashMap<>(Map.of("configCount",e.getValue().get(0),
"webSiteCount",e.getValue().get(1),
"sourceCount", e.getValue().get(2))));
result.add(tempMap);
}
result.forEach(mp -> mp.entrySet()
.forEach(e -> System.out.println(e.getKey() + ":" + e.getValue())));
打印
owner:pqr
ownerPresence:{sourceCount=42, webSiteCount=4, configCount=1}
owner:abc
ownerPresence:{sourceCount=22, webSiteCount=2, configCount=1}
owner:xyz
ownerPresence:{sourceCount=32, webSiteCount=3, configCount=1}
我有一个方法 fetchConfigsCount()
returns List<Map<String, Object>>
。
结果如下:
{
"web_id": "abc",
"count": 1
},
{
"web_id": "xyz",
"count": 1
},
{
"web_id": "pqr",
"count": 1
}
我们有另一种方法 fetchWebsitesCount()
,它也 returns 一个相同格式的响应。
web_id
是键,其值为所有者名称。
count
是另一个键,它的值是 int
.
{
"web_id": "abc",
"count": 2
},
{
"web_id": "xyz",
"count": 3
},
{
"web_id": "pqr",
"count": 4
}
我们有一个类型为 ArrayList<String>
:
List<String> listOfOwners = ["abc","xyz","pqr"];
我想收集所有这些东西并想创建如下结果:
result:[
{"owner": "abc",
"ownerPresence":{
"configCount":1,
"websiteCount":2
},
{"owner": "xyz",
"ownerPresence":{
"configCount":1,
"websiteCount":3
},
{"owner": "pqr",
"ownerPresence":{
"configCount":1,
"websiteCount":4
}]
我不确定如何在 Java 8 中做到这一点。
- 将初始地图列表重新映射到
Map<String, Integer>
:
static Map<String, Integer> convert(List<Map<String, Object>> list) {
return list
.stream()
.collect(Collectors.toMap(
m -> (String) m.get("web_id"),
m -> (Integer) m.get("count")
));
}
List<Map<String, Object>> configs = fetchConfigsCount();
List<Map<String, Object>> websites = fetchWebsitesCount();
Map<String, Integer> configMap = convert(configs);
Map<String, Integer> websiteMap = convert(websites);
- 创建一个 POJO 来表示列表条目:
class Pojo {
String owner;
Map<String, Integer> ownerPresence;
// boilerplate: constructor(s), getters/setters
}
- 流式传输所有者列表,并构建地图:
List<String> listOfOwners = Arrays.asList("abc","xyz","pqr");
List<Pojo> result = listOfOwners
.stream()
.map(owner -> new Pojo(
owner,
Map.of(
"configCount", configMap.get(owner),
"websiteCount", websiteMap.get(owner)
)
))
.collect(Collectors.toList());
更新
如果有其他输入,可以创建包装器映射以通过适当的键 "configCount", "websiteCount", "sourceCount"
等保存转换后的映射:
Map<String, Map<String, Integer>> bigMap = Map.of(
"configCount", convert(fetchConfigsCount()),
"websiteCount", convert(fetchWebsitesCount()),
"sourceCount", convert(fetchSourcesCount())
);
然后 Pojo
的地图可以这样创建:
List<Pojo> result = listOfOwners
.stream()
.map(owner -> new Pojo(
owner,
bigMap.keySet()
.stream() // Stream<String>
.collect(Collectors.toMap(
k -> k,
k -> bigMap.get(k).get(owner)
)) // Map<String, Integer>
))
.collect(Collectors.toList());
这是一种方法。
- 首先,只需将计数重新映射到
Map<String,List<Integer>>
- 然后简单地迭代 map,构建最终的 map 和列表。
List<Map<String, Object>> configCount =
List.of(Map.of("web_id", "abc", "count", 1),
Map.of("web_id", "xyz", "count", 1),
Map.of("web_id", "pqr", "count", 1));
List<Map<String, Object>> webCount =
List.of(Map.of("web_id", "abc", "count", 2),
Map.of("web_id", "xyz", "count", 3),
Map.of("web_id", "pqr", "count", 4));
List<Map<String, Object>> sourceCount =
List.of(Map.of("web_id", "abc", "count", 22),
Map.of("web_id", "xyz", "count", 32),
Map.of("web_id", "pqr", "count", 42));
Map<String, List<Integer>> map = Stream
.concat(configCount.stream(),
Stream.concat(webCount.stream(),
sourceCount.stream()))
.collect(Collectors.groupingBy(
mp -> (String) mp.get("web_id"),
Collectors.mapping(
mp -> (Integer) mp.get("count"),
Collectors.toList())));
上面创建了以下内容,其中第一个 List
值按顺序为“配置、网站和来源”。
pqr=[1, 4, 42]
abc=[1, 2, 22]
xyz=[1, 3, 32]
现在实例化一个最终列表来保存所有地图并完成。
List<Map<String, Object>> result = new ArrayList<>();
for (Entry<String, List<Integer>> e : map.entrySet()) {
Map<String, Object> tempMap = new HashMap<>();
tempMap.put("owner", e.getKey());
tempMap.put("ownerPresence",
new HashMap<>(Map.of("configCount",e.getValue().get(0),
"webSiteCount",e.getValue().get(1),
"sourceCount", e.getValue().get(2))));
result.add(tempMap);
}
result.forEach(mp -> mp.entrySet()
.forEach(e -> System.out.println(e.getKey() + ":" + e.getValue())));
打印
owner:pqr
ownerPresence:{sourceCount=42, webSiteCount=4, configCount=1}
owner:abc
ownerPresence:{sourceCount=22, webSiteCount=2, configCount=1}
owner:xyz
ownerPresence:{sourceCount=32, webSiteCount=3, configCount=1}