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?
Asked
Active
Viewed 108 times
3 Answers
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
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