Как посчитать среднее значение списка
Короткий ответ
average() у числового потока возвращает OptionalDouble:
void main() {
var grades = List.of(4, 5, 3, 5);
double average = grades.stream().mapToInt(Integer::intValue).average().orElse(0);
IO.println(average);
}Результат:
4.25Пустой список
Для пустого списка среднего нет — orElse() задаёт, что вернуть в этом случае:
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));
}Результат:
OptionalDouble.empty
0.0По группам
averagingInt() считает среднее для каждой группы:
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);
}Результат:
{A=85.0, B=70.0}Медиана
Медиана — среднее значение отсортированного списка — меньше зависит от выбросов:
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);
}Результат:
3100.0Частая ошибка
Делить целую сумму на целое количество. Дробная часть пропадает:
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());
}Результат:
4
4.333333333333333Функции из этого ответа
- IntStream.average() — Вычисляет среднее арифметическое чисел потока.
- Collectors.averagingDouble() — Сборщик, который вычисляет среднее значение числового поля.