Collectors.toMap 的 mergeFunction 是否允许修改其参数?
Is mergeFunction of Collectors.toMap allowed to modify its arguments?
我有一个嵌套映射流 Stream<Map<String, Map<String, String>>>
,我想通过转换为条目集流并调用 Collectors.toMap(...)
.为了确保正确组合具有重复外键的映射,我将以下 BinaryOperator
传递给 toMap(...)
函数:
(existingMap, newMap) -> {
existingMap.putAll(newMap);
return existingMap;
}
该代码暂时似乎可以工作,但我觉得我没有按预期使用 Collectors.toMap(...)
,因为我正在改变累加器和组合器中的值。
这是完整的代码片段:
mapsToCombine.flatMap(map -> map.entrySet().stream()).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (existingMap, newMap) -> {
existingMap.putAll(newMap);
return existingMap;
}));
似乎没有明确指定,但根据当前的实施,这样做是完全安全的。
您应该知道您正在修改的地图与源流中包含的地图完全相同,因此如果您的流是从数据结构构建的(例如 collection),则此数据结构将是操作后以不可预知的方式修改。它还意味着如果源多次包含相同的地图实例(这将违反 non-interference 规则),则整个操作可能会中断。或者如果源映射是不可变的。更糟糕的是,它可能 运行 多次没有问题并突然中断,在调试期间可能无法重现。
通常,如果此输入是在流操作期间创建的结果,则通过修改其中一个输入进行合并工作正常,例如由收藏家自己。您可以通过将 Entry::getValue
函数替换为 e -> new HashMap<>(e.getValue())
来轻松实现此目的。那么,non-interference的merge操作和map的可变性是有保证的,但是会创建比不在merge函数保存时创建map更多的临时map。
或者,您可以使用 groupingBy
,它允许您为以下值指定一个收集器:
Map<String, Map<String, String>> result
= mapsToCombine.flatMap(map -> map.entrySet().stream())
.collect(Collectors.groupingBy(Entry::getKey, Collector.of(HashMap::new,
(m,e) -> m.putAll(e.getValue()), (m1,m2) -> { m1.putAll(m2); return m1;})));
这不会修改任何源映射,只会创建一个可变结果映射,因此您可以在合并时放入它。
我有一个嵌套映射流 Stream<Map<String, Map<String, String>>>
,我想通过转换为条目集流并调用 Collectors.toMap(...)
.为了确保正确组合具有重复外键的映射,我将以下 BinaryOperator
传递给 toMap(...)
函数:
(existingMap, newMap) -> {
existingMap.putAll(newMap);
return existingMap;
}
该代码暂时似乎可以工作,但我觉得我没有按预期使用 Collectors.toMap(...)
,因为我正在改变累加器和组合器中的值。
这是完整的代码片段:
mapsToCombine.flatMap(map -> map.entrySet().stream()).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (existingMap, newMap) -> {
existingMap.putAll(newMap);
return existingMap;
}));
似乎没有明确指定,但根据当前的实施,这样做是完全安全的。
您应该知道您正在修改的地图与源流中包含的地图完全相同,因此如果您的流是从数据结构构建的(例如 collection),则此数据结构将是操作后以不可预知的方式修改。它还意味着如果源多次包含相同的地图实例(这将违反 non-interference 规则),则整个操作可能会中断。或者如果源映射是不可变的。更糟糕的是,它可能 运行 多次没有问题并突然中断,在调试期间可能无法重现。
通常,如果此输入是在流操作期间创建的结果,则通过修改其中一个输入进行合并工作正常,例如由收藏家自己。您可以通过将 Entry::getValue
函数替换为 e -> new HashMap<>(e.getValue())
来轻松实现此目的。那么,non-interference的merge操作和map的可变性是有保证的,但是会创建比不在merge函数保存时创建map更多的临时map。
或者,您可以使用 groupingBy
,它允许您为以下值指定一个收集器:
Map<String, Map<String, String>> result
= mapsToCombine.flatMap(map -> map.entrySet().stream())
.collect(Collectors.groupingBy(Entry::getKey, Collector.of(HashMap::new,
(m,e) -> m.putAll(e.getValue()), (m1,m2) -> { m1.putAll(m2); return m1;})));
这不会修改任何源映射,只会创建一个可变结果映射,因此您可以在合并时放入它。