38

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

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

List<Item> list = getListOfItems();

我想使用 Guava 库从该列表中获取最高价格的商品(我想是使用Ordering)。我的意思类似于这个 Groovy 代码:

list.max{it.price}

我怎么做?它的效率如何?

4

3 回答 3

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

于 2012-08-01T12:18:51.660 回答
38

根据 JB 的回答,在处理具有自然顺序的值时,您还可以使用一些速记,例如:

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

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

于 2013-01-10T12:43:20.347 回答
16

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

Collections 提供了对任何 Collection 进行操作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 实现以及文件等其他内容,并且可以通过过滤流轻松计算集合子集的最大值。如果你有一个大集合和一个昂贵的比较器(例如,字符串的自然排序),你可以使用并行流。

(旁白:理想情况下,当流类型实现 Comparable 时,Stream 将提供不带参数minmax重载。不幸的是,Java 不支持基于类型参数有条件地公开方法,因此不值得为此引入一个新的 StreamOfComparable 接口来扩展 Stream案子。)

于 2014-09-23T15:02:26.683 回答