簡體   English   中英

有沒有一種優雅的方法可以將地圖流減少到一個地圖

[英]Is there an elegant way to reduce a stream of maps to one 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結果(final或middle one)。

如果你想避免這種行為,請使用更有效的collect

R result = supplier.get();
for (T element : this stream)
    accumulator.accept(result, element);
return result;

所以表示accumulator.accept lambda不需要return任何值,而是根據element修改result

例:

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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM