【问题标题】:Applying a predicate with anyMatch() on a map keyset stream and returning some result when the predicate is false在映射键集流上应用带有 anyMatch() 的谓词,并在谓词为 false 时返回一些结果
【发布时间】:2019-07-29 17:23:47
【问题描述】:

我有一个类 Parcelle,它具有三个属性 numnatureautre_nature。以及 Parcelle listParcelles 的列表。我正在使用 Java 8 Streams,我想要实现的是按 num 分组并返回具有非空 natureautre_natureParcelle /em> 属性,否则只从组中随机返回一个 Parcelle。

Example :   
Input:   

    ligneParcelles[[num=1,nature=TC,autre_nature=TCC],  
                   [num=1,nature=TC,autre_nature=null],
                   [num=2,nature=TC,autre_nature=null],
                   [num=3,nature=TC,autre_nature=null],
                   [num=3,nature=Alpha,autre_nature=null],
                   [num=4,nature=TC,autre_nature=TC]
                   [num=4,nature=TC,autre_nature=null]]
Output :   
    ligneParcelles [[num=1,nature=TC,autre_nature=TCC],  
                   [num=2,nature=TC,autre_nature=null],
                   [num=3,nature=Alpha,autre_nature=null],
                   [num=4,nature=TC,autre_nature=TC]]

为了分组,我使用了以下代码:

Map<String, List<Parcelle>> mapLignesParcelles = listParcelles.stream()                                                    

          .collect(Collectors.groupingBy(lp->lp.getNum()+""));  

但我不确定要使用什么来获得最终结果,我可以流式传输 mapLignesParcelles 键集,并且我想到了带有谓词 lp.getNature()!=null &amp;&amp; lp.getAutre_Nature() !=null 的任何匹配,但是我该如何表达这个事实当谓词不成立时返回任何元素?

【问题讨论】:

  • 如果单个num 有更多匹配lp.getNature()!=null &amp;&amp; lp.getAutre_Nature() !=null 怎么办?
  • @Eugene 只是用 findFirst() 返回第一个,就像 Andrew 的回答一样

标签: java java-8 java-stream predicate


【解决方案1】:

您似乎正在寻找每个NumMap&lt;String, Parcelle&gt; 形式的单个Parcelle 的映射,而不是List 中的groupingBy。一种方法是在收集时使用toMap

Map<String, Parcelle> output = listParcelles.stream()
        .collect(Collectors.toMap(a -> a.getNum() + "", a -> a,
                (parcelle1, parcelle2) -> parcelle1.getNature() != null
                        && parcelle1.getAutre_nature() != null ? parcelle1 : parcelle2));

分组之前的另一种方式可能是:

Map<String, Parcelle> output = mapLignesParcelles.entrySet().stream()
        .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), e.getValue()
                .stream()
                .filter(lp -> lp.getNature() != null && lp.getAutre_nature() != null)
                .findAny()
                .orElse(e.getValue().get(new Random().nextInt(e.getValue().size())))))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

【讨论】:

  • 我使用了第一种方法并且成功了,Collectors 类上的 toMap 方法正是我需要的 mergeFunction 参数
【解决方案2】:
stream
    .filter(yourCondition)
    .findFirst()
    .orElse(randomlySelectedObject);

你有一个stream,你根据你的条件过滤它,你尝试获取第一个匹配条件的元素,如果找到则返回它,否则返回randomlySelectedObject

【讨论】:

  • 但是过滤操作后的流在谓词为false时不包含任何元素,那么randomSelectedObject将如何操作?
  • @mounaim 流没有,但原始集合(您构建流的基础)可以
  • @mounaim 除非您提供完整的 sn-p,否则我无法说得更清楚。我不知道你做了什么从输入转移到输出,但我很确定这不是你提到的 sn-p 所做的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多