我正在尝试将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));

10-04 18:10