如何使用来自几张地图的不同派生地图值有效地过滤和收集到生成的地图?

h.j*_*.k. 6 java dictionary java-8

我有一些Map对象K使用不同类型的值键入相同类型的对象,V1...VN为了这个问题的目的,不共享超类型*:

Map<K, V1> kv1
Map<K, V2> kv2
Map<K, V3> kv3
...
Map<K, VN> kvN
Run Code Online (Sandbox Code Playgroud)

我需要创建一个结果类型的地图Map<K, V>,通过不同地过滤每个地图,然后使用"值映射器"将值映射到这些地图上V1...VN常见类型的V新值(即a Function<? super Entry<K, VN>, ? extends V>).因此,我有以下static帮助方法来执行前两个步骤:

public static <K, VN, V> Map<K, V> filterAndMapValue(final Map<K, VN> map,
        final Predicate<? super Entry<K, VN>> predicate,
        final Function<? super Entry<K, VN>, ? extends V> mapper) {
    return map.entrySet().stream().filter(predicate)
            .collect(Collectors.toMap(Entry::getKey, mapper));
}
Run Code Online (Sandbox Code Playgroud)

我当前的用例使得可以安全地假设只有在每个映射上的过滤才会给出最终Map对象的不同键(每个映射中可以使用相同的键),但是如果在未来,我知道我可以提供一个补充mergeFunction表达来Collectors.toMap(Function, Function, BinaryOperator)正确处理这个问题.

最终代码现在读取如下内容:

Map<K,V> result = filterAndMapValue(kv1, predicateForKV1, mapV1toV);
result.putAll(filterAndMapValue(kv2, predicateForKV2, mapV2toV));
result.putAll(filterAndMapValue(kv2, predicateForKV3, mapV3toV));
...
result.putAll(filterAndMapValue(kvN, predicateForKVN, mapVNtoV));
// do something with result
Run Code Online (Sandbox Code Playgroud)

问题:有更有效的方法吗?这听起来像是另一种将东西(过滤后的地图)简化为最终集合(Map)的情况,它需要不同的缩减调用(值映射部分),而且我不确定我是否正确接近这种方式.

* - 如果他们这样做,那么我想V1...VN可以实现一个父方法,比如说V convertToV(Object... possiblyAdditionalArgumentsToPerformTheConversion),这样我的问题就减少到只为不同的地图应用不同形式的过滤.如果在这个替代假设下也有一个更简单的解决方案,请随意提及.

Hol*_*ger 2

如果您将方法更改为

\n\n
public static <K, VN, V> Stream<Entry<K, V>> filterAndMapValue(Map<K, VN> map,\n    Predicate<? super Entry<K, VN>> predicate,\n    Function<? super Entry<K, VN>, ? extends V> mapper) {\n\n    return map.entrySet().stream().filter(predicate)\n              .map(e->new AbstractMap.SimpleEntry<>(e.getKey(), mapper.apply(e)));\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以将该操作作为单个Stream操作执行,例如:

\n\n
Stream.of(filterAndMapValue(kv1, predicateForKV1, mapV1toV),\n          filterAndMapValue(kv2, predicateForKV2, mapV2toV),\n          filterAndMapValue(kv3, predicateForKV3, mapV3toV),\n          \xe2\x80\xa6)\n      .flatMap(Function.identity())\n      .collect(Collectors.toMap(Entry::getKey, Entry::getValue));\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,对于少量的输入映射,您可以使用Stream.concat,但随着数量的增加,上面显示的方法是更好的选择。

\n\n

我不期望\xe2\x80\x99 会有明显的性能提升,但这种方法将验证您的假设,即剩余条目中没有重复的键。

\n