给定一些 map ,是否有一种单行方法可以将它们的所有条目放入一张 map 中?
忽略空值、覆盖条目等问题,我想编写的代码是:
public static <K, V> Map<K, V> reduce(Map<K, V>... maps) {
return Arrays.stream(maps)
.reduce(new HashMap<K, V>(), (a, b) -> a.putAll(b));
}
但这会产生编译错误,因为 a.putAll(b)
是 void
。如果它返回 this
,它就可以工作。
为了解决这个问题,我编写了代码:
public static <K, V> Map<K, V> reduce(Map<K, V>... maps) {
return Arrays.stream(maps)
.reduce(new HashMap<K, V>(), (a, b) -> {a.putAll(b); return a;});
}
它可以编译并工作,但它是一个丑陋的 lambda;编码 return a;
感觉多余。
一种方法是重构实用方法:
public static <K, V> Map<K, V> reduce(Map<K, V> a, Map<K, V> b) {
a.putAll(b);
return a;
}
清理 lambda:
public static <K, V> Map<K, V> reduce(Map<K, V>... maps) {
return Arrays.stream(maps)
.reduce(new HashMap<K, V>(), (a, b) -> reduce(a, b));
}
但现在我有了一个虽然可重用但有点无用的实用方法。
有没有更优雅的方法来调用累加器上的方法并在 lambda 中返回它?
最佳答案
reduce
类似于
U result = identity;
for (T element : this stream)
result = accumulator.apply(result, element)
return result;
这意味着代表 accumulator.apply
的 lambda需要 return
结果(最终或中间结果)。
如果您想避免这种行为,请使用 collect
这更像是
R result = supplier.get();
for (T element : this stream)
accumulator.accept(result, element);
return result;
所以 lambda 代表 accumulator.accept
不需要return
除修改 result
外的任何值基于 element
.
例子:
public static <K, V> Map<K, V> reduce(Map<K, V>... maps) {
return Arrays.stream(maps)
.collect(HashMap::new, Map::putAll, Map::putAll);
// ^ ^
// | collect results from parallel streams
// collect results in single thread
}
关于java - 有没有一种优雅的方法可以将 map 流减少到一张 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26539113/