【问题标题】:Using Predicate in Java for Comparison在 Java 中使用谓词进行比较
【发布时间】:2013-10-11 17:31:35
【问题描述】:

我有一个方法应该将一个值与一个值列表进行比较。

比较函数可以小于、大于或等于。我遇到了这个Predicate 概念,我试图在这种情况下理解和实施。 以下是我的几个问题。

1) apache commons、guava 和 javax.sql 中定义了Predicate 类。他们之间有什么区别? (我尝试浏览文档但无法获取)

2) Guava 谓词是否仅用于过滤而不是布尔函数实现?

3) 我可以获取谓词的示例吗?

谢谢。

【问题讨论】:

  • 假设您在完成输入之前提交了此文件,我将为您提供疑问
  • Guava 有一个Predicate 接口,但它是用来过滤的。
  • @SotiriosDelimanolis 您可以使用(C++ 风格)谓词实现比较器,假设谓词在 a < b 时返回 true。例如,return less.apply(a, b) ? -1 : less.apply(b, a) ? 1 : 0;
  • @ChrisJester-Young 在这种情况下,一个 Predicate 是否应该返回所有较小的值,另一个返回相等的值,而另一个返回较大的值?
  • @SotiriosDelimanolis 重新考虑这一点,显然你不能直接使用Predicate,因为它是一元的,但假设有二进制版本,总是假设返回a 是否小于b .您只需交换参数即可测试另一个方向。至少,这就是它在 C++ 中的惯用方式。

标签: java guava


【解决方案1】:

假设您要测试给定集合的所有元素是否满足某个条件,这是一个使用 guava 的 Predicate 的示例(@ColinD 的评论指向大量已经存在的谓词,涉及 Comparable!):

public static class LessThan<T extends Comparable<T>> implements Predicate<T> {
  private final Comparable<T> value;

  public LessThan(final Comparable<T> value) {
    this.value = value;
  }

  @Override
  public boolean apply(final T input) {
    return value.compareTo(input) > 0;
  }
}

public static void main(final String[] args) {
  final Collection<Integer> things = Arrays.asList(1, 2, 3, 4);
  System.out.println(Iterables.all(things, new LessThan<Integer>(5)));
}

但除非您可以重用该谓词,否则您应该考虑使用 guava wiki 建议的非功能版本,例如:

public static boolean allLessThan(Collection<Integer> numbers, Integer value) {
   for (Integer each : numbers) {
      if (each >= value) {
         return false;
      }
   }
   return true;
}

【讨论】:

  • 谢谢...我可以使用 Iterables.any 方法并将其传递给集合以及完成我工作的谓词。这合乎逻辑吗?
  • 取决于你想达到什么?回到我的示例 LessThan 谓词 - 如果您通过 any() 过滤集合,它将返回 true,如果集合中至少有一个元素满足谓词,即小于设置值。有关更多选项,请参阅guava documentation
  • 仅供参考,您的 LessThan 谓词等同于 Range.lessThan(C)
  • 就知道这么简单的谓词应该是guava提供的,谢谢指点!
【解决方案2】:

我认为 Errandir 找到了您问题的核心:谓词是从输入到布尔值的函数,您想要进行三态比较。

回答您的其他问题:

Guava 谓词是否仅用于过滤而不是布尔函数实现?

没有。 Guava 谓词是一个返回布尔值的函数。 您可以根据某种过滤来表述大多数由谓词解决的问题,但它们可以在没有任何被过滤的集合的情况下使用。

我可以获取谓词的示例吗?

这是一个使用独立于集合的谓词:

Predicate<Person> isAuthorizedToBuyAlcohol = new Predicate<Person>() {
  public boolean apply(Person person) {
    return person.age() >= LEGAL_LIMIT;
  }
};

【讨论】:

  • 我可以使用Iterables.any 方法并将一个集合和一个谓词传递给它来完成我的工作。这合乎逻辑吗?
  • @LPD,是的。这是检查集合是否包含满足约束的内容的一种方法。
【解决方案3】:

简而言之,谓词之间的区别是:

  • apache-commons: 不是通用的;
  • guava: 是通用的;
  • javax.sql.rowset:用于RowSets(用于过滤SQL请求结果)。

我相信你想要Comparable 而不是Predicate

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 2020-04-30
    • 1970-01-01
    • 2016-10-10
    相关资源
    最近更新 更多