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

时间:2021-04-13 14:29:48

Let's say we have a Collection of Items:

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

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

List<Item> list = getListOfItems();

I would like to get an Item with a maximum price out of that list with Guava library (with Ordering, I presume). I mean something similar to this Groovy code:

我想从Guava库中获得一个具有最大价格的物品(订购,我推测)。我的意思是类似于这个Groovy代码:

list.max{it.price}

How do I do that? How efficient is it?

我怎么做?效率如何?

3 个解决方案

#1


56  

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

It's as efficient as it can be: it iterates through the items of the list, and returns the first of the Items having the maximum price: O(n).

它尽可能高效:它遍历列表中的项目,并返回具有最大价格的第一个项目:O(n)。

#2


34  

According to JB's answer, you can also use some shorthand when working with values which have natural order, for example:

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

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

See Ordering.natural() for details.

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

#3


12  

You can do this without Guava.

没有番石榴你就可以做到这一点。

Collections provides min and max methods that operate on any Collection, including overloads taking comparators. Here we use the Java 8 Comparator static methods with a lambda to concisely specify a comparator, but before Java 8 you can use an anonymous class:

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

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

These methods will throw NoSuchElementException if the collection is empty.

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


Java 8 streams provide min and max functions taking a comparator. These functions return Optional<T> to gracefully handle the stream being empty. The static methods in Comparator are useful for concisely specifying comparators, including the common case of the natural ordering. For this question, you'd use

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

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

This will work for any stream source, which includes all Collection implementations, as well as other things like files, and makes it easy to compute the max of a subset of a collection by filtering the stream. If you have a large collection and an expensive comparator (e.g., String's natural ordering), you can use a parallel stream.

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

(Aside: ideally Stream would provide min and max overloads taking no argument when the stream type implements Comparable. Unfortunately Java doesn't support conditionally exposing methods based on a type parameter, and it isn't worth introducing a new StreamOfComparable interface extending Stream just for this case.)

(旁白:理想情况下,当流类型实现Comparable时,Stream将提供min和max重载,不带参数。遗憾的是,Java不支持基于类型参数有条件地公开方法,并且不值得引入新的StreamOfComparable接口扩展Stream对于这种情况。)

#1


56  

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

It's as efficient as it can be: it iterates through the items of the list, and returns the first of the Items having the maximum price: O(n).

它尽可能高效:它遍历列表中的项目,并返回具有最大价格的第一个项目:O(n)。

#2


34  

According to JB's answer, you can also use some shorthand when working with values which have natural order, for example:

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

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

See Ordering.natural() for details.

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

#3


12  

You can do this without Guava.

没有番石榴你就可以做到这一点。

Collections provides min and max methods that operate on any Collection, including overloads taking comparators. Here we use the Java 8 Comparator static methods with a lambda to concisely specify a comparator, but before Java 8 you can use an anonymous class:

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

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

These methods will throw NoSuchElementException if the collection is empty.

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


Java 8 streams provide min and max functions taking a comparator. These functions return Optional<T> to gracefully handle the stream being empty. The static methods in Comparator are useful for concisely specifying comparators, including the common case of the natural ordering. For this question, you'd use

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

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

This will work for any stream source, which includes all Collection implementations, as well as other things like files, and makes it easy to compute the max of a subset of a collection by filtering the stream. If you have a large collection and an expensive comparator (e.g., String's natural ordering), you can use a parallel stream.

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

(Aside: ideally Stream would provide min and max overloads taking no argument when the stream type implements Comparable. Unfortunately Java doesn't support conditionally exposing methods based on a type parameter, and it isn't worth introducing a new StreamOfComparable interface extending Stream just for this case.)

(旁白:理想情况下,当流类型实现Comparable时,Stream将提供min和max重载,不带参数。遗憾的是,Java不支持基于类型参数有条件地公开方法,并且不值得引入新的StreamOfComparable接口扩展Stream对于这种情况。)