我正在尝试将Stream<Map<String, Map<String, String>>>
对象合并到具有所有Streams
中的键的单个映射中。
例如,
final Map<String, someOtherObjectToProcess> someObject;
final List<Map<String, Map<String, String>>> list = someObject.entrySet()
.stream()
.flatMap(this::getInfoStream)
.collect(Collectors.toList());
getInfoStream的签名是
public Stream<Map<String, Map<String, String>>> getInfoStream(Map.Entry<String, someOtherObjectToProcess> entry)
如果我使用
(Collectors.toList())
,则可以获取这些Map对象的列表。如果使用上述代码,则输出示例:
[{
"name" : {
"property":"value"
}
},
{
"name2" : {
"property":"value"
}
}]
但是我想用结构收集到地图中
{
"name" : {
"property":"value"
},
"name2" : {
"property":"value"
}
}
前提是密钥将是唯一的。
如何使用Collectors.toMap()或任何其他替代方法来做到这一点?
最佳答案
当你有
Stream<Map<String, Map<String, String>>> stream = ...
(我假设这是
.flatMap(this::getInfoStream)
的结果),您可以调用.flatMap(map -> map.entrySet().stream())
从所有地图创建条目流,这将产生
Stream<Map.Entry<String, Map<String, String>>>
。现在,从该流中,您需要做的就是从映射的每个条目中收集键和值。假设每个键在您可以使用的所有地图上都是唯一的
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
但是,如果键不是唯一的,则需要确定应在同一键的新映射中放置什么值。我们可以通过填写
...
部分来做到这一点.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (vOld, vNew) -> ...));
// ^^^
其中
vOld
保留当前在相同键下的结果映射中保留的值,而vNew
保留新值(来自当前流“iteration”)。例如,如果您想忽略新值,则可以简单地返回
(vOld, vNew) -> vOld
保留的旧值/当前值简而言之(假设唯一键):
Map<String, Map<String, String>> combinedMap =
/*your Stream<Map<String, Map<String, String>>>*/
.flatMap(map -> map.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));