2012-07-07 46 views
4

我正在尋找一種簡單的方法來執行Java集合上的聚合函數以確定產品集合的最低價格。但我不想用純java來做,而是用戶可以輸入某種DSL /腳本/表達式語言,因此需要儘可能簡單。Java:如何使用表達式語言方法來聚合(min,max,avg)集合元素屬性?

假設我有以下對象結構:

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) 

這看起來簡單得多給用戶,並在引擎蓋下應該做同樣聚集。

想到什麼方法?從網上搜索下面的東西來我的腦海:

感謝 克里斯托夫

+1

Groovy的嘗試......它內置到JDK。 – duffymo 2012-07-07 12:17:57

回答

0

Java 8 streams提供一些這方面的功能在相當流利的語法:

import static java.util.Comparator.comparingBy; 
/* ... */ 
BigDecimal minPrice = product1.offers.stream() 
    .min(comparingBy(o -> o.data.price));