Алгоритмы ·
‹ Previous Next ›
⏱ 5 min read Modified: 2026-07-18

Среднее арифметическое

Найти среднее арифметическое элементов массива — одна из первых задач, с которых начинают изучение алгоритмов. Решение состоит из двух шагов: сложить все элементы и разделить сумму на количество элементов. В этом уроке разберём классическое решение через цикл, современный вариант через Stream API, а также неочевидные моменты, на которых часто ошибаются: целочисленное деление и пустой массив.

1. Нахождение среднего арифметического через цикл

Рассмотрим реализацию алгоритма нахождения среднего арифметического элементов массива.

Сначала в цикле переберём все элементы массива и вычислим их сумму. После чего разделим сумму на длину массива:

public class AverageExample {
    public static void main(String[] args) {
        double[] nums = {10.1, 11.2, 12.3, 13.4, 14.5};
        double result = 0;

        for (double d : nums) {
            result += d;
        }
        System.out.println("Среднее арифметическое " + result / nums.length);
    }
}

Вывод программы:

Среднее арифметическое 12.3

Сложность алгоритма — O(n): каждый элемент массива посещается ровно один раз.

2. Среднее арифметическое через Stream API

Начиная с Java 8 ту же задачу можно решить одной строкой — методом average() из Stream API:

import java.util.Arrays;

public class AverageStreamExample {
    public static void main(String[] args) {
        double[] nums = {10.1, 11.2, 12.3, 13.4, 14.5};

        double average = Arrays.stream(nums)
                .average()
                .orElse(0);

        System.out.println("Среднее арифметическое " + average);
    }
}

Метод average() возвращает OptionalDouble, а не double. Так Stream API решает проблему пустого массива: среднее арифметическое нуля элементов не определено, поэтому для пустого массива вернётся пустой OptionalDouble. Метод orElse(0) задаёт значение по умолчанию на этот случай. Решение через цикл в той же ситуации вычислит 0.0 / 0 и молча выдаст NaN.

3. Целочисленный массив: деление и переполнение

С массивом типа int[] прямолинейное решение даёт неожиданный результат:

int[] nums = {1, 2, 3, 4};
int sum = 0;
for (int n : nums) {
    sum += n;
}
System.out.println(sum / nums.length);          // 2 — неверно!
System.out.println((double) sum / nums.length); // 2.5 — верно

Оба операнда sum и nums.length имеют тип int, поэтому выполняется целочисленное деление: дробная часть отбрасывается. Чтобы получить точный результат, достаточно привести один из операндов к double.

Важно

Выражение sum / nums.length с целочисленными операндами отбрасывает дробную часть ещё до присваивания результата переменной типа double. Приводите к double один из операндов деления, а не результат: (double) sum / nums.length. Более подробно о приведении типов читайте в уроке Преобразование и приведение примитивных типов

Вторая проблема — переполнение: сумма большого количества больших значений int может выйти за пределы диапазона int, и результат станет некорректным без каких-либо ошибок. Надёжнее накапливать сумму в переменной типа long либо использовать Stream API — для IntStream метод average() суммирует в long:

int[] big = {Integer.MAX_VALUE, Integer.MAX_VALUE};

double average = Arrays.stream(big)
        .average()
        .orElse(0);

System.out.println(average); // 2.147483647E9 — без переполнения

4. Что дальше: алгоритмы сортировки

Нахождение среднего арифметического — первый из стандартных алгоритмов, которые мы разбираем в этом разделе. Дальше рассмотрим алгоритмы сортировки массива, реализованные на Java.

Существует достаточно много алгоритмов сортировки и их модификаций: пузырьком, выбором, вставками, поразрядная, быстрая, пирамидальная, слиянием, сортировка Шелла, топологическая, быстрая с составными ключами. В следующих уроках мы реализуем некоторые из этих алгоритмов.

Часто задаваемые вопросы

Как найти среднее арифметическое массива в Java одной строкой?

Через Stream API: Arrays.stream(nums).average().orElse(0). Метод average() работает для int[], long[] и double[] и возвращает OptionalDouble.

Почему для массива {1, 2, 3, 4} получается 2 вместо 2.5?

Потому что и сумма, и длина массива имеют тип int, а деление двух int в Java — целочисленное: дробная часть отбрасывается. Приведите один из операндов к double: (double) sum / nums.length.

Что вернёт average() для пустого массива?

Пустой OptionalDouble, потому что среднее нуля элементов не определено. Значение по умолчанию задаётся через orElse(). Решение через цикл для пустого массива double[] вычислит 0.0 / 0 и вернёт NaN.

Есть ли готовый метод average() в классе Math или Arrays?

Нет. В java.lang.Math и java.util.Arrays такого метода нет. Стандартный способ — Arrays.stream(nums).average(), то есть метод average() у примитивных стримов IntStream, LongStream и DoubleStream.

Video Explanation

Prefer video format? Watch this lesson with examples and explanations.

Comments

Please log in or register to have a possibility to add comment.