【问题标题】:Java stream match as many predicates as possibleJava 流匹配尽可能多的谓词
【发布时间】:2018-08-17 15:14:10
【问题描述】:

希望根据定义为谓词的某些条件过滤列表(以下只是示例):

Predicate<Person> agePredicate = p -> p.age < 30;
Predicate<Person> dobPredicate = p -> p.dateOfBirth < 1980;
Predicate<Person> namePredicate = p -> p.name.startWith("a");

List<Predicate<Person>> predicates = Arrays.asList(agePredicate, dobPredicate, namePredicate);

List<Person> shortListPersons = listPersArrays.asList(listPersons).stream().filter(p -> predicates.stream().allMatch(f -> f.test(p))).limit(10).collect(Collectors.toList());

在我找不到任何人/足够多的人的情况下,我怎样才能获得符合尽可能多标准的人的列表 - 一种排名。

我的另一个选择是再次调用与上面相同的函数,但使用 anyMatch 代替,但它不会很准确。

有什么想法吗?谢谢!

【问题讨论】:

    标签: java java-stream predicate


    【解决方案1】:

    从您的问题中给出的代码开始:

    List<Predicate<Person>> predicates = Arrays.asList(agePredicate, dobPredicate, namePredicate);
    

    我们可以根据他们匹配的谓词数量对人员列表进行排序:

    List<Person> sortedListOfPeopleByPredicateMatchCOunt = 
      listPersArrays
        .asList(listPersons)
        .stream()
        .sorted(
          Comparator.comparingLong(p -> predicates.stream().filter(predicate -> predicate.test(p)).count()))
           // Reverse because we want higher numbers to come first.
           .reversed())
        .collect(Collectors.toList());
    

    【讨论】:

    • 太棒了!这正是我的想法,但我不知道如何使用谓词。
    【解决方案2】:

    只是对上述答案的扩展,如果您的目标是过滤符合尽可能多条件的集合,您可以创建一个复合Predicate&lt;Person&gt;,然后将其用于过滤。

    鉴于您的谓词列表:

    List<Predicate<Person>> predicates = Arrays.asList(agePredicate, dobPredicate, namePredicate);
    

    复合谓词可以这样创建:

    Predicate<Person> compositPredicate = predicates.stream()
                    .reduce(predicate -> false, Predicate::or);
    

    注意:由于归约操作需要一个标识值和or Predicate&lt;&gt; 类的操作不应用任何进一步的谓词 if 任何一个谓词都是true,我使用predicate -&gt; false 作为 一个身份值。

    现在,过滤集合变得更容易和更干净:

    List<Person> shortListPersons = persons.stream()
                                           .filter(compositPredicate)
                                           .collect(Collectors.toList());
    

    【讨论】:

    • 不直接回答问题,但 +1 表示谓词上的 reduce。您可以执行类似的操作,将谓词减少为给定 Person 的值,然后按给定的 Function 排序。
    猜你喜欢
    • 1970-01-01
    • 2018-08-06
    • 2014-07-26
    • 2019-06-12
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多