How to find the maximum value of a given element in a HashMap using java 8 streams
I have a product HashMap Every product has a price I know how to find the product with the highest price But using java 8 streams really puzzles me I tried this but had no luck:
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; }
Solution
The first problem is that since you want to find the largest product by price, you'd better use items Values () as the source of the stream, and then you will have stream < Product > instead of stream < map Entry< Integer,Product>>.
Second, the reduce operation does not have the correct type Therefore, for the current code to work properly, you need to do the following:
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;
Third, this overload of the reduce operation returns optional < T > Therefore, the receiver type of the result set must be optional < T > as shown above
Above, we return null if there is no value in optional
A better solution is to make the method return a type of optional < Product > This will provide documentation to you or your colleagues and all future users of your method, which may give a value with a null result
This is a better alternative, which can return null in the document and ensure that the user of this method unpacks the return value safely
Invalidity can be dangerous at some times, and using optional can take you a long way if appropriate
With all this in mind, your code will become:
// 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); }
//The example returns an 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; }
In any case, the max method is more suitable for this task than reduce, so it can be improved to:
Optional<Product> maxPriceProduct = items.values() .stream() .max(Comparator.comparingInt(Product::getPrice));