【问题标题】:Find matching predicate and using iterable.tryFind return the element from the list in java查找匹配的谓词并使用 iterable.tryFind 从 java 中的列表中返回元素
【发布时间】:2014-05-21 23:21:38
【问题描述】:

我有一个列表,我想要列表中与谓词匹配的元素。我从列表中找到与第一个谓词匹配的元素,如果第一个谓词不返回 true,则它与第二个谓词匹配。

这是一个例子:

案例1:

result = iterable.tryFind(List, Predicates.or(predicate1, predicate2)).orNull();

这段代码的问题是它找到了匹配任何这些谓词的第一个元素。即使列表中的第二个元素与第一个谓词匹配,在我的情况下应该给予更高的优先级。在这种情况下,我期望这里的结果作为第二个元素,但得到第一个元素(因为它是第一个元素与这些谓词之一匹配)。

案例2:

result = iterable.tryFind(List, Predicates.and(predicate1, predicate2)).orNull();

如果第一个谓词返回 false,这显然行不通。

案例 3:

result = iterable.tryFind(List, predicate1).orNull();

if(result == null)
result = iterable.tryFind(List, predicate2).orNull();

这对我有用,但它看起来很混乱并且违背了函数式编程的目的。

还有其他方法可以从列表中获取适合我的场景的元素吗?

【问题讨论】:

  • 是否真的因为你有分支而破坏了目的?什么困扰着你:分支、双重迭代,还是别的什么?您可以通过映射而不是过滤获得单次迭代的结果,因此您知道哪个谓词匹配,过滤与任何谓词不匹配的元素,然后减少以保留第一个匹配项,优先级从第一个谓词。它真的会变得不那么混乱吗(在 Java 中)?
  • @FrankPavageau :分支困扰着我。我希望它能够在不分离谓词的情况下工作。如果我理解正确,您建议的将与此类似。我想这是我使它工作的唯一方法。
  • 我不认为“函数式编程”意味着删除所有控制流:某些时候必须做一些事情,当你过滤一个集合时,它只是隐藏在方法中,而不是被删除。跨度>

标签: java guava


【解决方案1】:

您可以使用Optional.or 而不是Predicate.or 来获得您想要的:

result = Iterables.tryFind(list, predicate1)
         .or(Iterables.tryFind(list, predicate2))
         .orNull();

【讨论】:

  • 问题是Iterables.tryFind(list, predicate2) 总是被评估。您需要来自 Javascript 的 || 或来自 LISP 的 or。在 Java 中,它只有在 tryFind 是惰性的并且 Optional 会在需要时评估其参数时才能工作。
  • 这是我的解决方案的缺点。懒惰的tryFind 可以用Supplier 实现,但这只有在它不返回absent 时才有效。
猜你喜欢
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 2012-02-19
  • 1970-01-01
相关资源
最近更新 更多