如何在 Java 中动态构造谓词
Posted
技术标签:
【中文标题】如何在 Java 中动态构造谓词【英文标题】:How to construct predicates dynamically in Java 【发布时间】:2021-04-07 23:49:13 【问题描述】:我不确定这是否可能,经过大量研究后,我最终来到这里寻求您的帮助甚至指导。 所以,假设我有一个 json 数组,该数组中有 10 种不同类型的对象。这是一个通过体育游戏 API 检索的 json。 我需要做的是在我的应用程序中过滤这些对象。我正在使用 JAVA,到目前为止,我最终将使用流过滤器和谓词。我知道我可以创建不同类型的谓词并将它们放在 stream.filter() 函数中,但是是否可以以某种方式动态地做到这一点?
例如,我需要按时间过滤这个数组。这个谓词将是
return p -> p.getTime() > 1;
然后:
return match.stream().filter( predicate ).collect(Collectors.<Match>toList());
如果另一个过滤器有另一个条件是团队名称怎么办。是否可以添加一些其他谓词的方式,并在这两者之间添加“AND”“OR”条件?我需要使用具有不同谓词的一个过滤器函数动态地执行此操作。
有没有办法制作像自定义查询这样的东西来将其存储在数据库中并检索它并像谓词一样使用它?或者谓词本身是否可以存储在数据库中?
如果我完全错了,请指导我找到另一种方法来做到这一点。否则将不胜感激。谢谢大家,祝大家新年快乐。 :)
【问题讨论】:
and
s 上有一个 and
方法,它返回一个新的组合方法。您可以通过首先将它们(动态地)组合成一个来构建您在过滤器中使用的那个。 docs.oracle.com/javase/8/docs/api/java/util/function/…
edit 您的问题并发布示例 JSON 字符串以及您想从该字符串中获取的 List
。
你的意思是Predicate#and
和Predicate#or
(它们都是有效的静态方法)?
我不明白为什么这被否决了。我是新来的。不知道怎么表达不是很正常吗?或者编程中存在什么?反正。我不需要显示代码。我需要一个理论来寻找更好的方向。我不需要规范,这就是为什么我不显示任何 JSON 或任何代码的原因。考虑一个来自 dB 的过滤器,同时让过滤器基于该过滤器构造一个谓词。
【参考方案1】:
这是一个有趣的问题。考虑到数据湖场景,我认为这也不会是罕见的面孔。
我认为,正如上面评论中所建议的,申请的方式是拥有一个Predicate
。您可能有一个谓词将条件应用为AND
或OR
,然后将其提供给流处理器。像这样(假设您有一个基类 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
进行动态编译。这可能有点复杂。但是,您可以考虑使用像 Groovy 这样的基于 JVM 的脚本语言来处理这些事情。
【讨论】:
感谢您的回答。我的项目一直处于搁置状态,所以我没有查看论坛。我将不得不检查一下,但通过这个解决方案,我想我可能会找到一种方法来做到这一点。谢谢以上是关于如何在 Java 中动态构造谓词的主要内容,如果未能解决你的问题,请参考以下文章