0

I am trying to calculate the average value in Map collections. Every Key has exactly one value. How can I cast entry.getValue() so that compiler does not show errors?

Eclipse code

Miki
  • 31
  • 7
  • 1
    Don't post pictures of code, post code. Do you know what kind of numbers your map contains, i.e. can you use `Map` instead or are you forced to use `? extends Number` as value type? – knittl May 02 '20 at 18:46

3 Answers3

2

If you are really forced to handle a map of type Map<String, ? extends Number> and not e.g. Map<String, Double>, you can call doubleValue() on the number instance to convert this number to a double (the result is not guaranteed to be exact and may have been rounded).

public static double avg(final Map<String, ? extends Number> map) {
    double sum = 0d;
    for (final var entry : map.entrySet()) {
        sum += entry.getValue().doubleValue();
    }
    return sum / map.size();
}

But if you can change the signature of your method, I'd suggest that instead:

public static double avg(final Map<String, Double> map) {
    double sum = 0d;
    for (final var entry : map.entrySet()) {
        sum += entry.getValue();
    }
    return sum / map.size();
}
knittl
  • 246,190
  • 53
  • 318
  • 364
1

you can try

 sum = sum + entry.getValue().floatValue()
1

As the others already noted, you can just call doubleValue or floatValue.

You can also give the caller the opportunity to tell you how he wants you to get the value:

    public static double avg(final Map<String, ? extends Number> map) {
        return avg(map, Number::doubleValue);
    }

    public static <T> double avg(final Map<String, ? extends T> map, ToDoubleFunction<? super T> toDoubleFunction) {
        double sum = 0d;
        for (final var entry : map.entrySet()) {
            sum += toDoubleFunction.applyAsDouble(entry.getValue());
        }
        return sum / map.size();
    }

You could also use the Streams API for that:

    public static double avg(final Map<String, ? extends Number> map) {
        return avg(map, Number::doubleValue);
    }

    public static <T> double avg(final Map<String, ? extends T> map, ToDoubleFunction<? super T> toDoubleFunction) {
        return map.values().stream()
                .mapToDouble(toDoubleFunction)
                .average()
                .orElse(0.0);
    }
Felix
  • 2,256
  • 2
  • 15
  • 35