[英]Java: How to aggregate (min,max,avg) of collection element attributes with an expression language approach?
我正在寻找一种简单的方法来对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)
这看起来对用户来说更简单,并且应该在引擎盖下进行相同的聚合。
你想到了什么方法? 从网上搜索,我想到了以下几点:
谢谢Christoph
LambdaJ是一个使用普通Java API解决此问题的库: https : //code.google.com/p/lambdaj/wiki/LambdajFeatures
Person maxAgePerson = selectMax(personsList, on(Person.class).getAge() );
其中selectMax
和on
是来自Lambda类的静态导入。
Java 8流以合理流畅的语法提供了一些此功能:
import static java.util.Comparator.comparingBy;
/* ... */
BigDecimal minPrice = product1.offers.stream()
.min(comparingBy(o -> o.data.price));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.