与@Anton Balaniuc 的回答略有不同。
Map<String, App> resultSet =
siteIdToAppNameToAppMap.values()
.stream()
.map(Map::values)
.flatMap(Collection::stream)
.collect(Collectors.toMap(App::getToken,
Function.identity(), (left, right) -> {
throw new RuntimeException("duplicate key");
},
HashMap::new));
此解决方案从siteIdToAppNameToAppMap 映射值创建一个流,然后我们对映射值执行map 操作以产生Stream<Collection<App>>,然后flatMap 将所有嵌套的Stream<Collection<App>> 折叠为@ 987654327@,最后toMap收集器将返回一个Collector,它将元素累积到一个Map中,其键是App::getToken的返回值,值是Function.identity()的返回值。
上面的函数(left, right) -> { throw new RuntimeException("duplicate key");}是merge函数,用来解决同一个key关联的值之间的冲突。在这种特殊情况下,您不需要它,但它只是在那里,因此我们可以使用 toMap 收集器的重载,然后允许我们指定我们特别想要一个 HashMap 实例。
所有,其他 toMap 重载不保证返回的 Map 的类型、可变性、可序列化性或线程安全性。
注意 - 如果您不希望重复键,那么抛出异常(如上所示)是可行的方法,因为它表明存在问题而不是执行其他操作。但是,如果您想在重复键的情况下返回一个值,那么您可以根据需要将合并函数简单地更改为 (left, right) -> left 或 (left, right) -> right。