如何在Java中动态构造谓词

问题描述

我不确定这是否可行,经过大量研究后,我最终来到这里寻求您的帮助甚至指导。 所以,假设我有一个 json 数组,数组中有 10 种不同类型的对象。这是一个 json,正在通过带有体育游戏的 API 进行检索。 我需要做的是在我的应用程序中过滤这些对象。我正在使用 JAVA,到目前为止我已经结束了我将使用流过滤器和谓词。我知道我可以创建不同类型的谓词并将它们放在 stream.filter() 函数中,但是否可以以某种方式动态地执行此操作?

例如,我需要按时间过滤这个数组。这个谓词将是

return p -> p.getTime() > 1;

然后:

return match.stream().filter( predicate ).collect(Collectors.<Match>toList());

如果另一个过滤器有另一个条件是团队名称怎么办。是否可以添加一些其他谓词的方式并在这两者之间添加“AND”“OR”条件?我需要使用一个带有不同谓词的过滤器函数来动态执行此操作。

有没有办法制作像自定义查询这样的东西来将它存储在数据库中并检索它并像谓词一样使用它?或者谓词本身可以存储在数据库中吗?

如果我完全错了,请指导我找到另一种方法来做到这一点。否则,将不胜感激。谢谢大家,祝大家新年快乐。 :)

解决方法

这是一个有趣的问题。而且我认为考虑到数据湖场景,这也不会是罕见的面孔。

我认为,正如上面评论中所建议的,申请的方式是拥有一个 Predicate。您可能有一个谓词将条件应用为 ANDOR,然后将其提供给流处理器。像这样(假设您有一个基类 Data,您已将 API 输出映射到该基类):

/* Create the predicate with the conditions. Showing 2 here with an "AND" combination. */
Predicate<? extends Data> p = d -> d.getTime() > 1;
p.and( d -> d.getName().equals( "Football" ) ); //Consider ".or()" here,if that is what you need.

/* Supply this predicate to the stream processor. */
match.stream().filter( p ).collect(Collectors.<Match>toList());

使用 and() 调用与在流处理器上一个接一个地调用 .filter() 相同。像这样:

stream.filter(...).filter(...)...

因此,您将能够在 for 循环中构造这样的流调用。

有没有办法制作像自定义查询这样的东西来将它存储在数据库中并检索它并像谓词一样使用它?或者谓词本身可以存储在数据库中吗?

您可以在您的 Predicate 中执行此操作。也就是说,您可以调用数据库来获取 Java 代码,而不是编写如上所示的逻辑。但是,您必须使用 JavaCompiler 进行动态编译。那可能有点复杂。但是,您可以考虑使用基于 JVM 的脚本语言,例如 Groovy。