我正在寻找一种在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)
对于用户来说,这看起来要简单得多,并且应该在幕后完成同样的聚合。
你想到了什么方法?从网络搜索中,我想到了以下几点:
谢谢克里斯多夫
发布于 2013-04-21 04:15:57
LambdaJ是一个使用普通Java:https://code.google.com/p/lambdaj/wiki/LambdajFeatures来解决这个问题的库。
Person maxAgePerson = selectMax(personsList, on(Person.class).getAge() );
其中selectMax
和on
是来自兰卜达类的静态导入。
发布于 2014-10-11 06:48:45
Java 8流以相当流畅的语法提供了其中一些功能:
import static java.util.Comparator.comparingBy;
/* ... */
BigDecimal minPrice = product1.offers.stream()
.min(comparingBy(o -> o.data.price));
https://stackoverflow.com/questions/11374922
复制