【问题标题】:Combine Java 8 predicates with disjunction将 Java 8 谓词与析取结合使用
【发布时间】:2016-10-12 07:29:23
【问题描述】:

假设我有一个数组或一个状态列表,并且想要过滤一个列表以查找其状态与任何给定值匹配的元素。所以我继续创建一个谓词。我首先通过与第一个比较来初始化它,然后使用or 添加更多条件,这导致谓词最少但代码很多:

Predicate<Rec> predicate = null;
for (SendStatus status : statuss) {
    Predicate<Rec> innerPred = nr -> nr.getStatus() == status;
    if (predicate == null)
        predicate = innerPred;
    else
        predicate = predicate.or(innerpred);
}

更优雅的是,我想出了以下代码:

Predicate<Rec> predicate = nr -> false;
for (SendStatus status : statuss) {
    predicate = predicate.or(nr -> nr.getStatus() == status);
}

这看起来更好,但在链的开头有一个无用的谓词。 Apache Collections 有一个 AnyPredicate 可以由任意数量的谓词组成,我基本上是在寻找替代品。

这个多余的谓词可以接受吗?有没有更优雅的写法?

【问题讨论】:

  • 为什么不使用Predicate&lt;Rec&gt; predicate = nr -&gt; statuss.contains(nr .getStatus()) ;
  • 嘿@Jerry06,在这种情况下你是完全正确的(我更改了我的代码以完全使用它)。但是,我让这个问题代表更一般的情况。

标签: java lambda predicate


【解决方案1】:

这个怎么样,假设statussCollection&lt;SendStatus&gt;

Predicate<Rec> predicate = nr -> statuss.stream().anyMatch(status -> nr.getStatus() == status);

或者这个,如果statussSendStatus[]

Predicate<Rec> predicate = nr -> Arrays.stream(statuss).anyMatch(status -> nr.getStatus() == status);

或者像suggested by @Jerry06 in a comment那样做,如果statussSet&lt;SendStatus&gt;会更快,并且比上面的流式收集解决方案更简单:

Predicate<Rec> predicate = nr -> statuss.contains(nr.getStatus());

【讨论】:

  • 因为我的问题是“将 Java 8 谓词与析取结合起来”,这可能会解决错误的问题。每次调用谓词时创建一个流感觉有点奇怪。
  • 你也在问“有没有更优雅的方式来写这个?”。该答案为您提供了三个选项可供选择。最后一个例子是(恕我直言)尽可能优雅。
猜你喜欢
  • 1970-01-01
  • 2018-07-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多