2012-08-01 73 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接口扩展流只是为了这种情况。)