Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Агрегация Java: Массивы

Распространенный вариант использования циклов с массивами — агрегация. Агрегацией называются любые вычисления, которые, как правило, строятся на основе всего набора данных, например, поиск максимального, среднего, суммы и так далее. Процесс агрегации не требует знания нового синтаксиса, но влияет на алгоритм решения задач. Поэтому имеет смысл рассмотреть его отдельно. Начнем с поиска максимального.

class MyArrayUtils {
    public static Integer calculateMax(int[] numbers) {
        // Если массив пустой, то у него не может быть максимального
        // В подобных ситуациях принято возвращать null
        if (numbers.length == 0) {
            return null;
        }

        // Сравнение элементов нужно начать с какого-то первого элемента
        var max = numbers[0]; // Принимаем за максимальное первый элемент
        // Обход начинаем со второго элемента
        for (var i = 1; i < numbers.length; i++) {
            var currentElement = numbers[i];
            // Если текущий элемент больше максимального,
            // то он становится максимальным
            if (currentElement > max) {
                max = currentElement;
            }
        }

        // Не забываем вернуть максимальное число
        return max;
    }
}

int[] numbers1 = {};
System.out.println(MyArrayUtils.calculateMax(numbers1)); // => null

int[] numbers2 = { 3, 2, -10, 38, 0 };
System.out.println(MyArrayUtils.calculateMax(numbers2)); // => 38

https://replit.com/@hexlet/java-arrays-aggregation-max#MyArrayUtils.java

Почему это пример агрегации? Здесь мы видим вычисление, которое включает в себя сравнение всех элементов для поиска одного, которое станет результатом этой операции.

Обратите внимание, что начальным значением max взят первый элемент, а не, скажем, число 0. Ведь может оказаться так, что все числа в массиве меньше 0, и тогда мы получим неверный ответ.

Теперь рассмотрим поиск суммы:

class MyArrayUtils {
    public static int calculateSum(int[] numbers) {
        // Начальное значение суммы
        var sum = 0;
        for (var i = 0; i < numbers.length; i++) {
            // Поочередно складываем все элементы
            sum += numbers[i];
        }

        return sum;
    }
}

// Сумма элементов всегда возвращает какое-то число
// Если массив пустой, то сумма его элементов 0
int[] numbers1 = {};
System.out.println(MyArrayUtils.calculateSum(numbers1)); // => 0

int[] numbers2 = { 3, 2, -10, 38, 0 };
System.out.println(MyArrayUtils.calculateSum(numbers2)); // => 33

// Процесс вычислений
var sum = 0;
sum = sum + 3; // 3
sum = sum + 2; // 5
sum = sum + -10; // -5
sum = sum + 38; // 33
sum = sum + 0; // 33

https://replit.com/@hexlet/java-arrays-aggregation-sum#MyArrayUtils.java

Алгоритм поиска суммы значительно проще, но обладает парой важных нюансов.

Чему равна сумма элементов пустого массива? С точки зрения математики такая сумма равна 0. Что в принципе совпадает со здравым смыслом. Если у нас нет яблок, значит у нас есть 0 яблок (количество яблок равно нулю). Функции в программировании работают по этой логике.

Второй момент связан с начальным элементом суммы. У переменной sum есть начальное значение равное 0. Зачем вообще задавать значение? Любая повторяющаяся операция начинается с какого-то значения. Нельзя просто так объявить переменную и начать с ней работать внутри цикла. Это приведет к неверному результату. Представим что мы хотим посчитать не сумму, а произведение чисел:

int mult = 0;

// первая итерация цикла
mult = mult * 2; // ?

В результате такого вызова, внутри mult окажется 0. Почему для умножения нужна единица? Очень легко проверить, что все остальные варианты приведут к неверному результату. Если начальное значение будет равно 0, то результатом умножения всегда будет 0.

В математике существует понятие нейтральный элемент операции (у каждой операции свой элемент). Это понятие имеет очень простой смысл. Операция с этим элементом не изменяет то значение, над которым проводится операция. В сложении любое число плюс ноль дает само число. При вычитании то же самое. Даже у конкатенации есть нейтральный элемент – это пустая строка: "" + "one" будет "one".

Агрегация далеко не всегда означает, что коллекция элементов сводится к некоторому простому значению. Результатом агрегации может быть сколь угодно сложная структура, например, массив. Подобные примеры часто встречаются в реальной жизни. Самый простой пример – это список уникальных слов в тексте.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 25 000 ₸ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 28 ноября

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»