Перебор элементов массивов в 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 поддерживает это с помощью многомерных массивов, которые по сути являются массивами массивов.