2012-08-01 56 views
37

比方說,我們有項目的集合:如何從列表中番石榴獲得最大的()元素

class Item { 
    public String title; 
    public int price; 
} 

List<Item> list = getListOfItems(); 

我想獲得一個項目與最高價的是,清單,番石榴庫(與我推測)。我的意思是類似這樣的Groovy代碼的東西:

list.max{it.price} 

我該怎麼辦呢?它有多高效?

回答

55
Ordering<Item> o = new Ordering<Item>() { 
    @Override 
    public int compare(Item left, Item right) { 
     return Ints.compare(left.price, right.price); 
    } 
}; 
return o.max(list); 

它是有效率,因爲它可以:它在列表中的項目迭代,並返回第一個具有最高價格的項目:爲O(n)。

+0

如果價格不是int。用番石榴的方式來使用這種方法? – gstackoverflow 2014-01-24 09:06:55

+0

價格的類型是無關緊要的。您只需提供按價格比較物料的訂單。假設它是BigDecimal,你可以使用'return left.price.compareTo(right.price)'。 – 2014-01-24 09:37:07

34

根據JB的答案,你也可以與具有自然順序值工作時,例如使用一些簡寫:

Ordering.<Integer> natural().max(listOfIntegers); 

詳見Ordering.natural()

11

你可以做到這一點沒有番石榴。

收藏提供了minmax方法在任何集合上運行,包括採取比較器的超載。在這裏,我們使用Java 8比較靜態方法是lambda簡明地指定一個比較,但Java 8之前,你可以使用匿名類:

Item max = Collections.max(list, Comparator.comparingInt(i -> i.price)); 

這些方法將拋出NoSuchElementException異常,如果集合爲空。


爪哇8流提供minmax功能採取的比較器。這些函數返回Optional<T>以正常處理流爲空。比較器中的靜態方法可用於簡明地指定比較器,包括自然排序的常見情況。對於這個問題,你會使用

Optional<Item> max = list.stream().max(Comparator.comparingInt(i -> i.price)); 

這對於任何流源,其中包括所有集合的實現,以及其他像文件的工作,而且很容易計算的一個子集的最大通過過濾流來收集。如果你有一個大集合和一個昂貴的比較器(例如,字符串的自然順序),你可以使用並行流。不幸的是,Java不支持基於類型參數有條件地公開方法,並且不值得引入新的StreamOfComparable接口擴展流只是爲了這種情況。)