Перебор массива в Java. Основные способы перебора массива в Java на примерах
Нередко Java-программисту необходимо реализовать обработку таких наборов данных, как массивы и коллекции. Чаще всего речь идёт о переборе всех значений массива. В этой статье мы поговорим, как это делать стандартным и расширенным способом. И приведём соответствующие примеры.
Чтобы выполнить перебор массива в Java, применяют один из операторов цикла: for, while, do…while. В большинстве случаев используют именно for:
int aNums[] = < 2, 4, 6 >; for (int i = 0; i
Так как это стандартная операция, разработчики ввели дополнительный формат, обеспечивающий более рациональную и упрощённую реализацию перебора элементов в массиве Java. Эту реализацию можно сравнить с использованием цикла foreach в иных языках программирования. Некоторые называют её формой расширенного цикла for:
for (type variable : collection) < // некоторые операторы // . >Что тут у нас есть: • type – тип внутренней переменной, имеющий имя variable; • variable – внутренняя переменная type-типа, видимая в границах блока фигурных скобок. Она итерационна и сохраняет элементы из набора данных collection; • collection – набор данных, перебираемых в цикле поочерёдно. И вот как раз в качестве набора таких данных может выступать и массив, и коллекция.
Итак, в расширенном цикле for на Java осуществляется последовательный перебор всех элементов массива либо коллекции. При этом число итераций цикла равняется числу элементов в массиве. На каждой итерации значение какого-нибудь элемента массива попадает в итерационную переменную variable, которую вы можете обрабатывать либо использовать. А цикл гарантирует, что произойдёт перебор или прохождение по всему массиву, начиная с первого элемента, заканчивая последним.
Давайте посмотрим, как это выглядит на примере.
Перебор массива чисел в Java
Продемонстрируем расширенный цикл for при обработке одномерного массива чисел типа int. В нашем примере реализован подсчёт количества парных чисел Java-массива:
// инициализируем одномерный массив A int[] A = < 1, 8, 3, 6, 5, 10, 31 , 24, 10, 13, 2, 4 >; int k = 0; // число парных чисел // расширенный цикл for for (int d : A) if (d % 2 == 0) k++; // k = 7Перебор массива объектов в Java
Представьте, что у нас есть класс Book, реализующий книгу:
class Book < String title; // название String author; // автор float price; // цена int year; // год выпуска >Давайте выполним перебор этого массива объектов, используя расширенный цикл for:
// объявляем одномерный массив типа Book Book B[]; // выделяем память для массива из четырёх ссылок на тип Book B = new Book[4]; // выделяем память для каждого элемента нашего массива for (int i=0; iРезультат перебора этого массива объектов в Java будет следующим:
Book: Book-3, Author-3 Book: Book-4, Author-4Перебор коллекции в Java
Также для примера продемонстрируем, как происходит обработка коллекции типа Integer посредством ArrayList. Как известно, класс нам ArrayList нам нужен для реализации динамического массива, способного увеличиваться либо уменьшаться по мере необходимости. Для использования этого класса следует подключить пакет java.util. Объявление класса ArrayList выглядит следующим образом:
class ArrayList
Здесь E – это тип объектов, сохраняемых в массиве. Класс Integer является классом-оберткой над типом int и представляет целочисленные значения. В нашем примере класс ArrayList, обрабатывающий объекты типа Integer, имеет следующий вид:
class ArrayList
Теперь давайте посмотрим на использование расширенного цикла for (одна из возможных реализаций):
// подключаем пакет java.util import java.util.*; . ArrayList A = new ArrayList(); // создаём коллекцию // добавляем элементы в коллекцию A.add(5); A.add(9); A.add(-20); A.add(11); A.add(7); // A = < 5, 9, -20, 11, 7 >// находим сумму элементов коллекции int sum = 0; for (Integer i : A) // расширенный цикл for sum += i; System.out.println("Sum = " + sum); // Sum = 12Плюсы и минусы расширенного цикла for для Java-массивов
Применение расширенного цикла for имеет ряд преимуществ: • повышенная рациональность и упрощённость, если сравнивать со стандартным использованием цикла for; • отпадает необходимость в применении дополнительной переменной цикла, не надо задавать её начальное значение, как и условие завершения цикла; • массив индексировать тоже не нужно; • такой цикл очень удобен при обработке коллекций.
Но есть и недостаток, который связан с тем, что у нас отсутствует доступ к индексу массива. В результате у нас снижается гибкость в оперировании итерационной переменной. А это иногда нужно, допустим, если надо выполнить перебор не всех элементов массива или коллекции. К примеру, в некоторых случаях у программистов возникают задачи по перебору лишь первых n-элементов либо элементов, лежащих на определённых позициях (четных или нечётных). Правда, данный недостаток мы можем обойти, если введём дополнительные переменные-итераторы и проверку соответствующих условий. Тем не менее лучше всего этот способ подходит именно для обычного перебора всех элементов массива в Java.
Хотите знать больше? Приходите на профессиональный курс по Java-программированию в OTUS!
Простой способ вывода массива в Java
При работе с языком программирования Java новички часто сталкиваются с проблемой вывода массива. Дело в том, что в Java массивы не переопределяют метод toString() . Это означает, что при попытке вывести массив непосредственно на печать, будет выведена строка, состоящая из имени класса, символа ‘@’ и шестнадцатеричного представления hashCode массива. Это стандартное поведение, определенное в Object.toString() . Вот пример такого вывода:
int[] array = new int[] ; System.out.println(array); // Выводит что-то вроде "[I@6bc7c054"Однако, в большинстве случаев хотелось бы получить более читаемый вывод, например, [1, 2, 3] . Как же это сделать?
Самый простой и удобный способ – использовать статический метод toString() из класса java.util.Arrays . Вот как это выглядит:
import java.util.Arrays; int[] array = new int[] ; System.out.println(Arrays.toString(array)); // Выводит "[1, 2, 3]"Этот метод работает не только с массивами примитивных типов, но и с массивами объектов. Вот пример с массивом строк:
import java.util.Arrays; String[] array = new String[] ; System.out.println(Arrays.toString(array)); // Выводит "[Alice, Bob, Charlie]"Таким образом, для вывода массива в Java достаточно импортировать класс java.util.Arrays и использовать его метод toString() . Это позволяет получить читаемое строковое представление массива, что особенно полезно при отладке программ.
Как вывести весь массив в java
Я правильно понимаю - что если я массиву Б присвою массив А (В=А). То присвою просто ссылку на А. Ссылку на В потеряю и начальное содержимое В - будет очищено потом при очистке мусора? int[] A = new int[3] <1,2,3>; int[] B = new int[3] ; B=A; // содержимое В потеряно A[1]=5; // в A[1] и B[1] теперь значение 5 A=null; //теперь ссылка на массив А только в Б?1,2,3>
Anatoly Уровень 22
22 апреля 2023
Теперь все встало на свои места
Vladimir Уровень 13
12 апреля 2023Хороший материал, спасибо автору! Единственный момент, на мой взгляд, лучше отобразить импорт класса Arrays, чтобы было понятно откуда методы по классу Arrays берутся.
Ислам Уровень 32
12 апреля 2023
отличная лекция, которая дает больше понимания о массивах в Java
Кирилл Загурный Уровень 21 Expert
12 апреля 2023
Отличный материал на закрепление темы массивов. Спасибо!
13 марта 2023
Автору спасибо, полезный и понятный материал!
15 февраля 2023У меня вопрос: создал массив и заполнил случайными числами. Не могу теперь понять как найти повторяющиеся числа в массиве
11 февраля 2023
Хорошая статья
СообществоJavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.
Подписывайтесь
Язык интерфейса
"Программистами не рождаются" © 2023 JavaRush
Скачивайте наши приложения
"Программистами не рождаются" © 2023 JavaRushЭтот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.
Как вывести весь массив в java
Метод Arrays.copyOf() принимает 2 параметра: копируемый массив и количество копируемых значений, которое определяет также длину нового массива. Т. к. мы хотим скопировать массив целиком, то указываем в качестве количества длину исходного массива.
Если вам требуется скопировать не весь массив, а только какую-то его часть, то вместо длины следует указать необходимое значение: это может быть как целочисленный литерал, так и значение переменной.
Следует иметь ввиду небольшой нюанс работы метода, связанный с тем, что если количество копируемых элементов указано больше, чем их содержит массив, то copyOf() дополнит итоговый массив значениями по умолчанию.
Пусть имеется заполненный массив чисел, в который необходимо добавить еще одно число. Т. к. размер уже созданного массива менять нельзя, то создадим новый с увеличенным размером:
int[] srcArr = ; int[] destArr = Arrays.copyOf(srcArr, srcArr.length + 3); System.out.println(Arrays.toString(destArr)); destArr[srcArr.length] = 6; destArr[srcArr.length + 1] = 7; System.out.println(Arrays.toString(destArr));[1, 2, 3, 4, 5, 0, 0, 0] [1, 2, 3, 4, 5, 6, 7, 0]Рассмотрим чуть более сложный пример:
String[] letters = ; int len = letters.length; int newLen = len + (int) (len * 0.75); System.out.println("Длина нового массива = " + newLen); String[] destArr = Arrays.copyOf(letters, newLen); System.out.println(Arrays.toString(destArr)); destArr[len] = "D"; System.out.println(Arrays.toString(destArr));Длина нового массива = 5 [A, B, C, null, null] [A, B, C, D, null]В данном коде создаются два массива типа String. Длина второго массива (newLen) вычисляется по формуле, которая позволяет увеличивать его размер на 75%. Также видно, что copyOf заполняет пустые ячейки null’ом.
2.3. Arrays.copyOfRange()
Если требуется скопировать значения не с начала массива (или не до конца), то необходимо использовать Arrays.copyOfRange() (появился в Java 1.6). Данный метод позволяет копировать определенный диапазон значений массива, начиная с указанного индекса:
int[] srcArr = ; int[] destArr = Arrays.copyOfRange(srcArr, 1, 3); System.out.println(Arrays.toString(destArr));Метод copyOfRange() принимает 3 параметра: исходный (копируемый) массив; индекс в исходном массиве, с которого будет начинаться копирование; третий параметр — конечный индекс до которого будут копироваться элементы (значение под этим индексом не включается в копирование).
Еще пример. Необходимо найти максимальное число, затем скопировать в новый массив все значения, которые находятся справа от этого числа, включая само число:
import java.util.Arrays; public class Main < public static void main(String[] args) < double[] srcArr = ; double max = srcArr[0]; int maxNumIndex = 0; for (int i = 1; i < srcArr.length; i++) < if (srcArr[i] >max) < maxNumIndex = i; max = srcArr[i]; >> double[] destArr = Arrays.copyOfRange(srcArr, maxNumIndex, srcArr.length); System.out.println(Arrays.toString(destArr)); > >[120.2, -4.8, 3.5, 70.2]Метод copyOfRange(), так же как и copyOf(), если количество копируемых элементов указано больше, чем их содержит массив, дополняет итоговый массив значениями по умолчанию.
2.4. System.arraycopy()
В Java есть еще один способ скопировать массив — с помощью нативного (native) метода arraycopy(), расположенного в классе System.
Его работа имеет принципиальное отличие от копирования элементов массива в цикле: он копирует не поэлементно, а целыми блоками памяти, что влияет положительно на производительность.
Данный класс находится в пакете java.lang, и его не нужно импортировать — это делается автоматически.
Нативными называются методы, реализация которых написана на каком-то другом языке, отличном от Java (например, С/C++), под конкретную ОС, что делает их код платформозависимым, т. е. «родным» для конкретной системы.
Методы, помеченные как native, не могут иметь тела и должны заканчиваться точкой с запятой.
Получается, что сигнатуру метода arraycopy() с ключевым словом native мы можем наблюдать в классе System, а вот реализация, написанная на языках C/C++, находится совсем в другом месте. Она является частью скомпилированной в виде машинного (бинарного) кода библиотеки внутри JVM.
Сигнатура обсуждаемого метода выглядит сложноватой, но к ней можно привыкнуть:
@IntrinsicCandidate public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)Запомнить последовательность аргументов, которые принимает метод, не сложно. Рассуждать можно следующим образом: из исходного массива (src), начиная с начальной позиции (srcPos), нужно скопировать данные в другой массив (dest), в такую-то позицию (destPos), в таком-то количестве (length).
Стоит отметить, что если массив назначения уже содержит данные, то arraycopy() их перезапишет.
Обратите внимание, что оба массива имеют тип Object. Это сделано для универсальности, чтобы данный метод мог работать с массивами любого типа.
Над сигнатурой метода мы также можем наблюдать аннотацию @IntrinsicCandidate (до Java 16 она называлась @HotSpotIntrinsicCandidate), сообщающую о том, что JVM вместо вызова кода, написанного на другом языке (а такие вызовы могут негативно влиять на производительность и делают невозможным выполнять оптимизации кода), может использовать внутреннюю (встроенную) реализацию данного метода, которая есть у JIT (Just-in-Time — технология увеличения производительности программ за счет компиляции часто используемых частей кода).
В режиме интерпретатора (когда JVM выполняет вашу программу байт-код за байт-кодом) виртуальной машиной будет запускаться native-версия arraycopy(), но проработав какое-то время и собрав статистику, при определенных условиях она будет рассматривать методы с подобными аннотациями как кандидаты на замену native-кода внутренним машинным кодом.
Разберем пример работы с arraycopy(). Пусть требуется удалить значение по индексу 0, а затем сдвинуть влево все числа, стоящие от него справа:
import java.util.Arrays; class Main < public static void main(String[] args) < int[] arr = ; System.arraycopy(arr, 1, arr, 0, arr.length - 1); System.out.println(Arrays.toString(arr)); arr[arr.length - 1] = 0; System.out.println(Arrays.toString(arr)); > >
