我正在尝试将一个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());
Run Code Online (Sandbox Code Playgroud)
getInfoStream 的签名是
public Stream<Map<String, Map<String, String>>> getInfoStream(Map.Entry<String, someOtherObjectToProcess> entry)
Run Code Online (Sandbox Code Playgroud)
如果我使用,(Collectors.toList())我可以获得这些 Map 对象的列表。
如果我使用上面的代码,示例输出:
[{
"name" : {
"property":"value"
}
},
{
"name2" : {
"property":"value"
}
}]
Run Code Online (Sandbox Code Playgroud)
但我想收集成具有结构的地图
{
"name" : {
"property":"value"
},
"name2" : {
"property":"value"
}
}
Run Code Online (Sandbox Code Playgroud)
前提是密钥是唯一的。
我如何使用 Collectors.toMap() 或任何其他替代方式来做到这一点?
当你有
Stream<Map<String, Map<String, String>>> stream = ...
Run Code Online (Sandbox Code Playgroud)
(我假设是的结果.flatMap(this::getInfoStream))你可以打电话
.flatMap(map -> map.entrySet().stream())
Run Code Online (Sandbox Code Playgroud)
从所有映射中创建条目流,这将产生Stream<Map.Entry<String, Map<String, String>>>.
现在,从该流中,您需要做的就是从映射的每个条目中收集键和值。假设每个键在您可以使用的所有地图中都是唯一的
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)
但如果键不唯一,您需要决定应在新映射中为同一键放置什么值。我们可以通过填写...部分来做到这一点
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (vOld, vNew) -> ...));
// ^^^
Run Code Online (Sandbox Code Playgroud)
其中vOld保存结果映射中当前在同一键下保存的值,并vNew保存新值(来自当前流“迭代”)。
例如,如果您想忽略新值,您可以简单地返回旧值/当前持有的值(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));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5245 次 |
| 最近记录: |