鉴于一些地图,是否有一种将所有条目放入一张地图的单行方式?
忽略空值,覆盖条目等问题,我想编码的是:
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中返回它?
答案 0 :(得分:14)
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;
所以代表accumulator.accept
的lambda不需要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
}