【问题标题】:How to get max() element from List in Guava如何从 Guava 的 List 中获取 max() 元素
【发布时间】:2012-07-30 08:00:16
【问题描述】:

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

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

List<Item> list = getListOfItems();

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

list.max{it.price}

我该怎么做?效率如何?

【问题讨论】:

    标签: java guava


    【解决方案1】:
    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)。

    【讨论】:

    • 如果价格不是整数。是否以番石榴方式使用这种方法?
    • 价格的类型无关紧要。您只需要提供按价格比较商品的订单。假设它是 BigDecimal,您将使用 return left.price.compareTo(right.price)
    【解决方案2】:

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

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

    详情请见Ordering.natural()

    【讨论】:

      【解决方案3】:

      不用番石榴也可以做到这一点。

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

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

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


      Java 8 流提供了带有比较器的 minmax 函数。这些函数返回Optional&lt;T&gt; 以优雅地处理空流。 Comparator 中的静态方法可用于简洁地指定比较器,包括自然排序的常见情况。对于这个问题,你会使用

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多