Распространенный вариант использования циклов с массивами — агрегация. Агрегацией называются любые вычисления, которые, как правило, строятся на основе всего набора данных, например, поиск максимального, среднего, суммы и так далее. Процесс агрегации не требует знания нового синтаксиса, но влияет на алгоритм решения задач. Поэтому имеет смысл рассмотреть его отдельно. Начнем с поиска максимального.
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"
.
Агрегация далеко не всегда означает, что коллекция элементов сводится к некоторому простому значению. Результатом агрегации может быть сколь угодно сложная структура, например, массив. Подобные примеры часто встречаются в реальной жизни. Самый простой пример – это список уникальных слов в тексте.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.