我正在寻找一种简单的方法来对 Java 集合执行聚合函数以确定例如一组产品的最低价格。但我不想用纯 java 来做,而是某种可以由用户输入的 DSL/脚本/表达式语言,因此需要尽可能简单。
假设我有以下对象结构:
Product:
id: product1
offers: [offer1, offer2]
Offer1:
id: offer1
data:
price: 10.99
shipCost: 3.99
Offer2:
id: offer2
data:
price: 5.99
shipCost: 3.99
在上面的示例中,最终结果将是这样的:
minPriceOfProduct1 = 5.99
现在我的应用程序的用户可以显示产品列表。 对于每种产品,他都希望获得最低价格,这是所有报价中的最低价格。用户无权访问底层数据存储,因此 SQL 不是一个选项。我们唯一拥有的是 java 对象。 我希望用户使用某种表达语言来表达这一点。
目前,我能够将 Freemarker 代码片段应用于每个产品以获取数据,或者做更多的事情来根据如下属性计算新值:
<#if (item.isProduct() && item.offers??) >
<#assign offerMinPrice = -1>
<#list item.offers as o>
<#if (offerMinPrice == -1 || ( o.data.priceCents?? && o.data.priceCents < offerMinPrice ) )>
<#assign offerMinPrice=o.data.priceCents! >
</#if>
</#list>
<#if offerMinPrice != -1>
${offerMinPrice}
<#else>
${priceCents}
</#if>
<#else>
${priceCents!}
</#if>
这行得通,但它是丑陋的代码,不仅让我的大脑流血。 我宁愿有某种更简单的表达语言方法,看起来像这样:
minOffersPrice = min(product.offers.data.price)
这对用户来说看起来更简单,并且应该在幕后进行相同的聚合。
您想到了什么方法?通过搜索网络,我想到了以下内容:
- MVEL 表达式语言 http://mvel.codehaus.org/MVEL+2.0+Operators (好像没有解决聚合函数)
- JoSQL http://josql.sourceforge.net/
- lambda 表达式或闭包之类的东西
- Java 中的 Rhino Javascript
- 结合 Java Reflections 或 apache commons beanutils 进行一些手动解析
谢谢 克里斯托夫
最佳答案
LambdaJ 是一个使用纯 Java api 解决此问题的库:https://code.google.com/p/lambdaj/wiki/LambdajFeatures
Person maxAgePerson = selectMax(personsList, on(Person.class).getAge() );
其中 selectMax
和 on
是从 Lambda 静态导入的类。
关于Java:如何使用表达式语言方法聚合(min、max、avg)集合元素属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11374922/