使用Java 8 Streams,如何在HashMap中查找给定元素的最大值

Rob*_*ker 6 java hashmap java-8 java-stream

我有一个产品的HashMap.每个产品都有价格.我知道如何找到具有最高价格的产品.但是使用Java 8 Streams真的让我很困惑.我试过这个但没有运气:

public Product getMostExpensiveProduct(HashMap<Integer, Product> items) {

    Product maxPriceProduct = items.entrySet()
            .stream()
            .reduce((Product a, Product b) ->
                    a.getPrice() < b.getPrice() ? b : a);

    return maxPriceProduct;
}
Run Code Online (Sandbox Code Playgroud)

Ous*_* D. 10

第一个问题是,既然你想要找到最大Product的价格,那么最好items.values()用作流的源,然后你将有一个Stream<Product>而不是一个Stream<Map.Entry<Integer, Product>>.

其次,reduce操作没有正确的类型.因此,要使当前代码正常工作,您需要执行以下操作:

Optional<Map.Entry<Integer, Product>> result = 
      items.entrySet()
           .stream()
           .reduce((Map.Entry<Integer, Product> a, Map.Entry<Integer, Product> b) ->
                        a.getValue().getPrice() < b.getValue().getPrice() ? b : a);

return result.isPresent() ? result.get().getValue() : null;
Run Code Online (Sandbox Code Playgroud)

第三,该reduce操作的重载返回一个,Optional<T>因此结果集的接收器类型必须Optional<T>如上所示.

在上面,我们将null在Optional中没有值的情况下返回.

更好的解决方案是使方法返回一个类型Optional<Product>.这将向您或您的同事以及您的方法的所有未来用户提供文档,其中可能会给出结果为空的值.

这是返回null文档的更好选择,并确保此方法的用户安全地解包返回值.

无效在某些时候可能是危险的,并且在适当的情况下利用Optional可以带您走很长的路.

考虑到所有这些,您的代码将成为:

// example without returning an `Optional<T>`

public Product getMostExpensiveProduct(HashMap<Integer, Product> items) {
        Optional<Product> maxPriceProduct = 
           items.values()
                .stream()
                .reduce((Product a, Product b) ->
                        a.getPrice() < b.getPrice() ? b : a);

        return maxPriceProduct.orElse(null);
}
Run Code Online (Sandbox Code Playgroud)

//示例返回一个 Optional<T>

public Optional<Product> getMostExpensiveProduct(HashMap<Integer, Product> items) {
            Optional<Product> maxPriceProduct = 
               items.values()
                    .stream()
                    .reduce((Product a, Product b) ->
                            a.getPrice() < b.getPrice() ? b : a);

            return maxPriceProduct;
 }
Run Code Online (Sandbox Code Playgroud)

无论如何,该max方法更适合于此任务而不是reduce,因此可以将其全部改进为:

Optional<Product> maxPriceProduct = 
           items.values()
                .stream()
                .max(Comparator.comparingInt(Product::getPrice));
Run Code Online (Sandbox Code Playgroud)