Average of list

Similar to finding the average of a numeric array, this example will compute the arithmetic mean of the values in an arraylist using java, java 8, guava and apache commons. In a comparable example we demonstrate how to find the average of a list of numbers in groovy.

Setup

private static List<Double> NUMBERS_FOR_AVERAGE = new ArrayList<Double>();

@Before
public void setup () {
    NUMBERS_FOR_AVERAGE.add(new Double(10));
    NUMBERS_FOR_AVERAGE.add(new Double(10));
    NUMBERS_FOR_AVERAGE.add(new Double(10));
    NUMBERS_FOR_AVERAGE.add(new Double(10));
    NUMBERS_FOR_AVERAGE.add(new Double(10));
    NUMBERS_FOR_AVERAGE.add(new Double(10));
    NUMBERS_FOR_AVERAGE.add(new Double(10));
    NUMBERS_FOR_AVERAGE.add(new Double(10));
    NUMBERS_FOR_AVERAGE.add(new Double(10));
    NUMBERS_FOR_AVERAGE.add(new Double(10));
}

Straight up Java

Using straight up java, we will iterate over the numbers list using an enhanced for each loop. Each iteration will add to the value to the sum variable then divide by the total number of elements in the list.

@Test
public void calculate_average_from_list_with_java () {
    
    Double sum = 0d;
    for (Double vals : NUMBERS_FOR_AVERAGE) {
        sum += vals;
    }
        
    sum =  sum / NUMBERS_FOR_AVERAGE.size();
    
    assertEquals(new Double(10), sum);
}

Java 8

Using java 8, we will convert the list to a stream then call mapToDouble. The mapToDouble will extract all the values and return a DoubleStream as the result. We will then call the average method defined on the DoubleStream interface to calculate the average of all numbers in the list. The DoubleStream also supports other statistical methods such as max(), min(), average(), count() and sum() and Double Summary Statistics is a state object for collecting them all. The average method will return a OptionalDouble describing the sum of the elements, or an empty optional if the stream is empty.

@Test
public void calculate_average_from_list_with_java8_lambda () {
    
    OptionalDouble average = NUMBERS_FOR_AVERAGE
            .stream()
            .mapToDouble(a -> a)
            .average();

    assertEquals(10, average.getAsDouble(), 0);
}

Google Guava

DoubleMath is a class implemented by google guava that covers arithmetic that isn't covered by java.lang.Math. In the snippet below, we will call DoubleMath.mean which will return the arithmetic mean of the provided list.

@Test
public void average_from_list_of_numbers_with_google_guava () {

    double average = DoubleMath.mean(NUMBERS_FOR_AVERAGE);
    assertEquals(10, average, 0);
}

Apache Commons

Mean, a class supported by apache commons, is a class that calculates the average of a set of values. We will call Mean.evaluate which return the mean of the elements contained in the arraylist.

@Test
public void average_from_list_of_numbers_with_apache_commons () {

    double[] elements = ArrayUtils.toPrimitive(
            NUMBERS_FOR_AVERAGE.toArray(new Double[NUMBERS_FOR_AVERAGE.size()]));
    
    Mean mean = new Mean();
    double average = mean.evaluate(elements);
    
    assertEquals(10, average, 0);
}

ReactiveX - RXJava

Passing in NUMBERSFORAVERAGE constant to Observable.from will create a emit the items to the sequence. Next, the averageDouble is part of Mathematical and Aggregate Operators will find the average numeric value of the source returning a single item. Then using java 8 instance method reference will print out the average result. averageInteger, averageLong and averageFloat exists if you are working with other data types.

@Test
public void calculate_average_of_array_rxjava() {

    Observable<Double> findAverage = Observable.from(NUMBERS_FOR_AVERAGE);
    averageDouble(findAverage).subscribe(System.out::println); // 10.0
}