'How to write a method that takes in a List of Integer, Float, Double and calculate the average?
I am trying to write a method that takes in a list of numeric values - eg List<Integer>
, List<Float>
, List<Double>
etc - and give me the average.
public double getAverage(List<? extends Number> stats) {
double sum = 0.00;
if(!stats.isEmpty()) {
// sum = stats.stream()
// .reduce(0, (a, b) -> a + b);
// return sum / stats.size();
}
}
These are the errors I get:
Operator '+' cannot be applied to 'capture<? extends java.lang.Number>', 'capture<? extends java.lang.Number>'
Solution 1:[1]
Create a DoubleStream
from Number
objects via Number#doubleValue()
, then use available reduction methods to calculate the average:
public double getAverage(List<? extends Number> stats) {
return stats.stream()
.mapToDouble(Number::doubleValue)
.summaryStatistics() // small overhead of unnecessary arithmetic
.getAverage(); // returns 0 when empty
}
or
public double getAverage(List<? extends Number> stats) {
return stats.stream()
.mapToDouble(Number::doubleValue)
.average()
.orElse(0); // explicit value for empty (but no other value makes sense)
}
depending on which style you prefer.
Solution 2:[2]
OptionalDouble average()
Where, OptionalDouble is a container object which may or may not contain a double value.
public class Test {
public static OptionalDouble getAverage(List<? extends Number> stats) {
return stats.
stream().
mapToDouble(d -> d.doubleValue()).
average();
}
public static void main(String[] args) throws IOException {
List<Integer> list = Arrays.asList(1, 4, 5, 67, 3);
if(getAverage(list).isPresent());
{
Double average = getAverage(list).getAsDouble();
System.out.println(average);
}
}
}
or
Using Goolge Guava
Double averge = Stats.meanOf(list);
it gets syntactically simplified
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |