使用Java 8 lambdas/transformations来组合和展平两个Maps

Mat*_*ell 7 java lambda java-8 java-stream

我有两张地图:

  • Map<A, Collection<B>> mapAB
  • Map<B, Collection<C>> mapBC

我想把它们变成一个Map<A, Collection<C>> mapAC,我想知道是否有一个平滑的方法来做lambdas和变换.在我的特定情况下,集合都是集合,但我想解决集合的问题.

我有一个想法是先将两张地图合并成a Map<A, Map<B, Collection<C>>>然后压平它,但我对任何方法都持开放态度.

数据注释:B应该只出现在与一个相关联的值集合中,A同样适用于mapBC(给定C的只映射到一个B).因此,应该只有一条从给定A到给定的路径C,尽管可能A -> B存在没有B -> C映射的映射,并且可能B -> C存在没有相应A -> B映射的映射.这些孤儿根本不会出现在结果中mapAC.

为了便于比较,以下是针对同一问题的纯粹必要方法的示例:

Map<A, Collection<C>> mapAC = new HashMap<>();

for (Entry<A, Collection<B>> entry : mapAB.entrySet()) {
    Collection<C> cs = new HashSet<>();

    for (B b : entry.getValue()) {
        Collection<C> origCs = mapBC.get(b);
        if (origCs != null) {
            cs.addAll(origCs);
        }
    }

    if (!cs.isEmpty()) {
        mapAC.put(entry.getKey(), cs);
    }
}
Run Code Online (Sandbox Code Playgroud)

Mis*_*sha 3

您没有指定如果第二张地图中不存在第一张地图中的某些 b 时您想要执行的操作,因此这可能不完全是您正在寻找的内容。

mapAB.entrySet().stream()
  .filter(e -> e.getValue().stream().anyMatch(mapBC::containsKey))
  .collect(toMap(
       Map.Entry::getKey,
       e->e.getValue().stream()
           .filter(mapBC::containsKey)
           .map(mapBC::get)
           .flatMap(Collection::stream)
           .collect(toList())
  ));
Run Code Online (Sandbox Code Playgroud)