Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to calculate the average of a list

Short answer

average() on a number stream returns an OptionalDouble:

void main() {
    var grades = List.of(4, 5, 3, 5);
    double average = grades.stream().mapToInt(Integer::intValue).average().orElse(0);
 
    IO.println(average);
}

Output:

4.25

An empty list

An empty list has no average — orElse() sets what to return in that case:

void main() {
    List<Integer> empty = List.of();
 
    IO.println(empty.stream().mapToInt(Integer::intValue).average());
    IO.println(empty.stream().mapToInt(Integer::intValue).average().orElse(0));
}

Output:

OptionalDouble.empty
0.0

By group

averagingInt() calculates the average for each group:

record Student(String group, int score) {}
 
void main() {
    var students = List.of(new Student("A", 80), new Student("B", 70), new Student("A", 90));
 
    var byGroup = students.stream()
            .collect(Collectors.groupingBy(Student::group, TreeMap::new, Collectors.averagingInt(Student::score)));
    IO.println(byGroup);
}

Output:

{A=85.0, B=70.0}

The median

The median — the middle value of a sorted list — depends less on outliers:

void main() {
    var salaries = List.of(3000, 3200, 2900, 50000);
    var sorted = salaries.stream().sorted().toList();
    int mid = sorted.size() / 2;
 
    double median = sorted.size() % 2 == 0
            ? (sorted.get(mid - 1) + sorted.get(mid)) / 2.0
            : sorted.get(mid);
    IO.println(median);
}

Output:

3100.0

Common mistake

Dividing an integer sum by an integer count. The fractional part is lost:

void main() {
    var grades = List.of(4, 5, 4);
    int sum = grades.stream().mapToInt(Integer::intValue).sum();
 
    IO.println(sum / grades.size());
    IO.println((double) sum / grades.size());
}

Output:

4
4.333333333333333

Functions used in this recipe

Thanks for reading!

Donate to the site — we work hard for you.