如何从Guava中的List获取max()元素

时间:2012-08-01 12:15:22

标签: java guava

假设我们有一个项目集合:

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

List<Item> list = getListOfItems();

我想从Guava库中获取一个具有最大价格的物品(我猜是Ordering)。我的意思是类似于这个Groovy代码:

list.max{it.price}

我该怎么做?效率如何?

3 个答案:

答案 0 :(得分:57)

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)。

答案 1 :(得分:37)

根据JB的回答,在使用具有自然顺序的值时,您也可以使用一些简写,例如:

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

有关详细信息,请参阅Ordering.natural()

答案 2 :(得分:13)

你可以在没有番石榴的情况下做到这一点。

集合提供了对任何集合进行操作的minmax方法,包括使用比较器的重载。这里我们使用带有lambda的Java 8 Comparator静态方法来简明地指定比较器,但在Java 8之前,您可以使用匿名类:

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

如果集合为空,这些方法将抛出NoSuchElementException。


Java 8流提供minmax函数作为比较器。这些函数返回Optional<T>以正常处理流为空的流。 Comparator中的静态方法对于简明地指定比较器非常有用,包括自然排序的常见情况。对于这个问题,你可以使用

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

这适用于任何流源,包括所有Collection实现,以及文件等其他内容,并且可以通过过滤流来轻松计算集合子集的最大值。如果您有一个大型集合和一个昂贵的比较器(例如,String的自然排序),您可以使用并行流。

(除此之外:理想情况下Stream会提供minmax重载,当流类型实现Comparable时不带参数。不幸的是,Java不支持基于类型参数有条件地暴露方法,并且它不是不值得为这种情况引入一个新的StreamOfComparable接口,扩展Stream。)