W3docs

Перебор элементов массивов в Java

Перебирайте массивы Java с помощью классического for, расширенного for-each и streams.

Читать array[0], array[1], array[2] вручную перестаёт работать примерно с длиной 3. Как только вы создали массив, Java предоставляет несколько способов обойти каждый элемент — выбирайте тот, который подходит для вашей задачи. На этой странице рассматриваются: индексный for, расширенный for (for-each), потоки массивов и как выбрать между ними.

Классический цикл for

Индексный for — самая гибкая форма, и только он даёт вам текущую позицию:

int[] scores = {90, 85, 73, 100, 62};
for (int i = 0; i < scores.length; i++) {
  System.out.println(i + ": " + scores[i]);
}

Используйте его, когда нужно:

  • получить индекс (для вывода, сравнения соседних элементов, пропуска вперёд)
  • обойти массив в обратном направлении — for (int i = scores.length - 1; i >= 0; i--)
  • шагать с шагом больше одного — i += 2
  • изменять массив — присваивая значение scores[i]

Граница всегда i < array.length, а не захардкоженное число. Если массив позже изменит размер (или будет передан откуда-то ещё), цикл всё равно будет работать.

length — это поле, поэтому скобок нет: пишите scores.length, а не scores.length(). (Строки устроены иначе — у String есть метод length().) Когда массив пуст, length равно 0 и тело цикла никогда не выполняется — именно то, что нужно, без лишних проверок. Общая механика описана в главе о цикле for.

Расширенный for — «for-each»

Когда нужно только значение каждого элемента по порядку, расширенный for короче и понятнее:

int[] scores = {90, 85, 73, 100, 62};
int sum = 0;
for (int score : scores) {
  sum += score;
}
System.out.println("sum = " + sum);

Читайте двоеточие как «в»: «для каждого int score в scores». Переменная цикла — это свежая копия каждого элемента. Получить индекс таким способом нельзя, и изменить массив через score тоже нельзя — присваивание score просто перепривязывает локальную переменную.

Используйте расширенный for, когда нужно «что-то сделать с каждым значением». Используйте классический for, когда важен индекс.

Чтение и запись внутри цикла

Внутри классического for выражение array[i] = newValue изменяет массив на месте:

int[] scores = {90, 85, 73, 100, 62};
for (int i = 0; i < scores.length; i++) {
  scores[i] = scores[i] + 5;     // give everyone a 5-point bonus
}

Расширенный for не может этого делать для примитивов — score = score + 5 меняет только локальную копию:

for (int score : scores) {
  score = score + 5;             // no effect on scores
}

Для массивов объектов переменная цикла по-прежнему ссылается на тот же объект, что и слот массива, поэтому вызов мутирующих методов на ней действительно изменяет то, что видит массив. Но переназначение переменной — нет.

Потоки (streams) над массивами

Для числовых массивов вспомогательный метод Arrays.stream(...) даёт API в стиле конвейера:

import java.util.Arrays;

int[] scores = {90, 85, 73, 100, 62};
int total = Arrays.stream(scores).sum();
double avg  = Arrays.stream(scores).average().orElse(0);
int max     = Arrays.stream(scores).max().orElse(0);

Для массивов объектов Arrays.stream(...) возвращает Stream<T> со стандартными методами filter/map/reduce:

String[] names = {"Ada", "Linus", "Grace"};
long shortOnes = Arrays.stream(names).filter(n -> n.length() <= 3).count();

Потоки выразительны, но не бесплатны — для напряжённых внутренних циклов обычный for работает быстрее и его проще отлаживать. Используйте потоки, когда хотите подчеркнуть намерение (сумма, фильтр-затем-подсчёт, группировка, преобразование). Полный API конвейера описан в Java streams.

forEach со стороны массива

Метода array.forEach(...) не существует. Ближайшие аналоги — Arrays.stream(arr).forEach(...) (для числовых или объектных массивов) или, для массивов объектов, сокращение Arrays.asList(arr).forEach(...). В большинстве случаев обычный for или расширенный for вполне подходят — не тянитесь за forEach только ради другого синтаксиса.

Выбор цикла

Что нужноИспользовать
Индекс (или шаг, или обратный порядок)классический for
Только значения по порядкурасширенный for
sum/avg/min/max/filter для чиселArrays.stream(...)
Преобразование массива в новыйклассический for или поток + toArray
Изменение массива на местеклассический for

Рабочий пример

java— editable, runs on the server

Что дальше

Теперь вы умеете создавать массивы и обходить их в любом направлении. В реальных задачах данные часто двумерны — сетка, таблица, игровое поле — и Java поддерживает это с помощью многомерных массивов, которые по сути являются массивами массивов.

Практика

Практика
Какой цикл следует использовать, если нужен индекс каждого элемента?
Какой цикл следует использовать, если нужен индекс каждого элемента?
Was this page helpful?