【问题标题】:API to express an operation to test whether one `Predicate` is stricter than another `Predicate`?API 来表达一个操作来测试一个`Predicate`是否比另一个`Predicate`更严格?
【发布时间】:2016-11-24 01:47:33
【问题描述】:

在 Java 中是否有某种标准方式来表达一个操作来测试一个 Predicate 是否比另一个 Predicate 更严格?

我可以想象像pred1.isStricterThan(pred2) 这样的东西,但是我在 API 中看不到这样的东西:https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html 和https://google.github.io/guava/releases/19.0/api/docs/com/google/common/base/Predicate.html .

这种类型的检查可能有用,例如重复使用缓存的搜索结果。

我看到了isEqual() 和equals(),这可能会有所帮助,但还有可能进行进一步优化...

编辑:

例子:

  1. string.contains("xy") 比 string.contains("x") 更严格
  2. string.contains("xy") && string.contains("ab") 比 string.contains("xy") 更严格
  3. x > 3 比 x > 2 更严格
  4. string.contains("abc") 不比 string.contains("cd") 更严格

严格性检查方法当然必须根据具体情况巧妙实施。

编辑 2&3:更严格的谓词在用于过滤时,应返回不太严格的谓词的子集。

编辑 4:注意:我不是要求 实现。相反,我问的是是否有一些 API 可以以标准方式表达这些检查。

【问题讨论】:

  • “更严格”是什么意思?如果你能清楚而准确地定义,我就有可能给出答案。
  • @Bohemian - 我假设这意味着对于在同一域上运行的两个谓词,更严格的谓词的 test() 方法(对于 Java 版本)返回 true 的子集不太严格的谓词评估为true,仅此而已。
  • @Bohemian:谢谢,我添加了 3 个示例和 1 个反例
  • 不,没有,因为没有理智的方法来测试这个,当然不是Predicate提供的接口。除非两个实例都知道彼此内部的极其详细的信息,否则无法进行这种检查。听起来有点像“我们可以解决停机问题吗”。
  • 不,没有,因为在特定情况之外,这样的检查是不可能的。这就是它的全部内容。

标签: java guava predicate


【解决方案1】:

您所描述的是graph。您可以使用 Google Guava 的新 graph API 来定义谓词严格度图并进行查询:

Predicate<String> containsX = string -> string.contains("x");
Predicate<String> containsXy = string -> string.contains("xy");
Predicate<String> containsXyAndAb = string -> string.contains("xy") 
        && string.contains("ab");
Predicate<Integer> greaterThan2 = x -> x > 2;
Predicate<Integer> greaterThan3 = x -> x > 3;
Predicate<String> containsAbc = string -> string.contains("abc");
Predicate<String> containsCd = string -> string.contains("cd");

MutableGraph<Predicate<?>> predicateStrictnessGraph = GraphBuilder.directed().build();

predicateStrictnessGraph.addNode(containsX);
predicateStrictnessGraph.addNode(containsXy);
predicateStrictnessGraph.addNode(containsXyAndAb);
predicateStrictnessGraph.addNode(greaterThan3);
predicateStrictnessGraph.addNode(containsAbc);
predicateStrictnessGraph.addNode(containsCd);

predicateStrictnessGraph.putEdge(containsXy, containsX);
predicateStrictnessGraph.putEdge(containsXyAndAb, containsXy);
predicateStrictnessGraph.putEdge(greaterThan3, greaterThan2);

boolean isContainsXyStricterThanContainsX =
        Graphs.reachableNodes(predicateStrictnessGraph, containsXy)
                .contains(containsX);
// result: true

boolean isContainsXyStricterThanContainsXyAndAb =
        Graphs.reachableNodes(predicateStrictnessGraph, containsXy)
                .contains(containsXyAndAb);
// result: false

为了进一步说明这一点,请考虑在图中查询比指定谓词更严格的谓词:

Predicate<String> containsAb = string -> string.contains("ab");
predicateStrictnessGraph.addNode(containsAb);
predicateStrictnessGraph.putEdge(containsAbc, containsAb);
predicateStrictnessGraph.putEdge(containsXyAndAb, containsAb);
Set<Predicate<?>> containsAbAndStricterPredicates =
        Graphs.reachableNodes(Graphs.transpose(predicateStrictnessGraph), containsAb);
// result: [containsAb, containsAbc, containsXyAndAb]

更多详情请见GraphsExplained · google/guava Wiki。

【讨论】:

  • 这需要有人建立一个包含所有条件的图表,并且有无限数量的条件,因此图表会占用大量内存。
  • @ChaiT.Rex “严格性检查方法当然必须逐案巧妙地实施”(KarolDepka)。单个代码库必须有有限数量的谓词才能定义其严格性。
  • 问题是关于一个名为isStricterThan 的方法,它在其标准库中采用Predicate Java 类的两个实例,它允许所有谓词,而不仅仅是少数几个。如果您将可能的搜索限制为仅几个示例,则重用缓存搜索结果的示例使用没有意义。很少有人使用只能搜索手动输入的谓词列表的搜索引擎。
  • 问题是关于类似一个名为isStricterThan的方法;一些“标准”。只要搜索引擎可以确定给定搜索查询谓词的相对严格性并将其适当地插入到图中,图 ADT 就可以与缓存的搜索结果一起使用。每当从缓存中清除结果时,也需要更新图表。
猜你喜欢
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
  • 2014-02-27
  • 2016-01-06
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多