【问题标题】:ignoring null or Optional.empty values when mapping映射时忽略 null 或 Optional.empty 值
【发布时间】:2019-03-12 20:25:18
【问题描述】:

有没有映射这个,而不是循环遍历它? 在某些情况下,值不应该放在地图中,所以我想忽略这些:

Map<A, String> returnMap = new HashMap<>();
Map<A, List<Long>> mapLByA = //...
mapLByA.forEach((k, v) -> {
    Optional<String> strOp = someMethod(v);
    if (str.isPresent()) {
        returnMap.put(k, strOp.get());
    }
});
return returnMap;

【问题讨论】:

    标签: java java-8 functional-programming java-stream


    【解决方案1】:

    您可以将列表值映射到可选字符串值,然后过滤掉空的可选项,最后收集到一个映射。您无需显式定义returnMap。

    return mapLByA.entrySet().stream()
            .map(e -> Map.entry(e.getKey(), someMethod(e.getValue())))
            .filter(e -> e.getValue().isPresent())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    

    编辑:

    Map.entry 是在 Java 9 中引入的。对于 Java 8,请改用此 map 语句:

    .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), someMethod(e.getValue())))
    

    【讨论】:

    • Map.entry?奇怪,Map里面没有这个方法,一个Map.Entry是抽象的?这可以重构吗?
    • @CCC 它是在 Java 9 中引入的。如果您使用的是 Java 8,则可以使用 AbstractMap.SimpleEntry。
    • 非常感谢。只是一个小细节 collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get()));
    【解决方案2】:

    您仍然需要在外部或内部循环,无法绕过它。但是您可以将该代码简化为一行,但无法判断它是否使其更具可读性:

    mapLByA.forEach((k, v) -> someMethod(v).ifPresent(s -> returnedMap.put(k, s)));
    

    【讨论】:

      【解决方案3】:

      您可以在上下文中简单地使用ifPresent:

      mapLByA.forEach((k, v) -> 
              someMethod(v).ifPresent(optional -> 
                      returnMap.put(k, optional)));
      

      【讨论】:

      • 与mapping 相比,对我来说似乎更具可读性(相关)。
      猜你喜欢
      • 2020-11-25
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 2020-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多