Java 8 Hash Map

I have a map Map<String, List<Double> , and I would like to find the maximum (or minimum) value in all lists. The function should return the maximum (or minimum) value and the key belonging to this value.

Signature may be

public static Pair<String,Double> getKeyValue(Map<String, List<Double>> map, BinaryOperator<Double> function)

which gets the mapping and function Double::max or Double::min

How can I implement this efficiently (and beautifully) using java 8, stream api?

+6
source share
2 answers

A BinaryOperator not a good specification for this task, it is straightforward to use in recovery to obtain the corresponding value, for example. minimum or maximum, however, it is not suitable for returning a bound value, such as the value of the Map s key. Using this method implies that the implementation must perform additional operations to find out what BinaryOperator really did in order to select the correct key value during the reduction. Worse, it cannot guarantee that BinaryOperator doing something that allows this kind of reduction, for example. an operator can return a value that is not one of its arguments.

For such a task, a Comparator is the best choice because it is designed to indicate the order and perform related operations, such as finding maximum and minimum. An implementation might look like this:

 public static Pair<String,Double> getMinimumKeyValue( Map<String, List<Double>> map, Comparator<Double> function) { return map.entrySet().stream() .map(e->new Pair<>(e.getKey(), e.getValue().stream().min(function).get())) .min(Comparator.comparing(Pair::getRight, function)).get(); } 

It is called getMinimumKeyValue , since it will return the minimum key / value pair when passed to Comparator.naturalOrder() .

But you can get the most by going through Comparator.reverseOrder() .

And it is easy to modify to support a wider range of use cases:

 public static <K,V> Pair<K,V> getMinKeyValue( Map<K, ? extends Collection<V>> map, Comparator<? super V> function) { return map.entrySet().stream() .map(e->new Pair<>(e.getKey(), e.getValue().stream().min(function).get())) .min(Comparator.comparing(Pair::getRight, function)).get(); } 

This still works to get Pair<String,Double> from Map<String, List<Double>> , but can do a lot more ...

+4
source

You can try the following:

 public static Pair<String,Double> getKeyValue(Map<String,List<Double>> map, BinaryOperator<Double> function) { return map.entrySet().stream() .map(e -> new Pair<String,Double>(e.getKey(),e.getValue().stream().reduce(function).get())) .reduce((p1,p2) -> function.apply(p1.getValue(),p2.getValue()).equals(p1.getValue()) ? p1 : p2) .get(); } 

Explanation:

First you associate each Entry<String,List<Double>> with Pair<String,Double> , where this is the min (or max) value of the list and the key remains unchanged, then you compare each Pair<String,Double> to find that which has the lowest (or highest) value.

+4
source

Source: https://habr.com/ru/post/976639/


All Articles