Calculating average of an array list?
Why use a clumsy for loop with an index when you have the enhanced for loop?
private double calculateAverage(List <Integer> marks) {
Integer sum = 0;
if(!marks.isEmpty()) {
for (Integer mark : marks) {
sum += mark;
}
return sum.doubleValue() / marks.size();
}
return sum;
}
Update: As several others have already pointed out, this becomes much simpler using Streams with Java 8 and up:
private double calculateAverage(List <Integer> marks) {
return marks.stream()
.mapToDouble(d -> d)
.average()
.orElse(0.0)
}
Use a double for the sum, otherwise you are doing an integer division and you won't get any decimals:
private double calculateAverage(List <Integer> marks) {
if (marks == null || marks.isEmpty()) {
return 0;
}
double sum = 0;
for (Integer mark : marks) {
sum += mark;
}
return sum / marks.size();
}
or using the Java 8 stream API:
return marks.stream().mapToInt(i -> i).average().orElse(0);
From Java8 onward you can get the average of the values from a List as follows:
List<Integer> intList = Arrays.asList(1,2,2,3,1,5);
Double average = intList.stream().mapToInt(val -> val).average().orElse(0.0);
This has the advantage of having no moving parts. It can be easily adapted to work with a List of other types of object by changing the map method call.
For example with Doubles:
List<Double> dblList = Arrays.asList(1.1,2.1,2.2,3.1,1.5,5.3);
Double average = dblList.stream().mapToDouble(val -> val).average().orElse(0.0);
NB. mapToDouble is required because it returns a DoubleStream which has an average
method, while using map
does not.
or BigDecimals:
@Test
public void bigDecimalListAveragedCorrectly() {
List<BigDecimal> bdList = Arrays.asList(valueOf(1.1),valueOf(2.1),valueOf(2.2),valueOf(3.1),valueOf(1.5),valueOf(5.3));
Double average = bdList.stream().mapToDouble(BigDecimal::doubleValue).average().orElse(0.0);
assertEquals(2.55, average, 0.000001);
}
using orElse(0.0)
removes problems with the Optional object returned from the average
being 'not present'.
With Java 8 it is a bit easier:
OptionalDouble average = marks
.stream()
.mapToDouble(a -> a)
.average();
Thus your average value is average.getAsDouble()
return average.isPresent() ? average.getAsDouble() : 0;