Код
Код
#База знаний
  • 9018

Массивы в Java: создаём, заполняем, используем

Учимся работать с массивами в Java. Всё разбираем на примерах.

Массив — это структура данных, которая хранит набор пронумерованных значений одного типа.

Допустим, у нас есть класс из десяти учеников и нам нужно сохранить их оценки. Для этого можно создать десять переменных:

int mark1 = 4;
int mark2 = 3;
int mark3 = 5;
int mark4 = 3;
int mark5 = 2;
int mark6 = 4;
int mark7 = 4;
int mark8 = 3;
int mark9 = 4;
int mark10 = 2;

А если в нашем классе будет не десяток учеников, а в десять раз больше, не заводить же нам 100 переменных! На выручку приходят массивы.


Артём Авдеев

Java-разработчик, преподаёт в Skillbox, осваивает машинное обучение.


Как объявить одномерный массив

С помощью квадратных скобок и специального слова new.

Такой синтаксис пришёл из языка C:

тип_массива название_переменной[] = new тип_массива[размер_массива];

Но в Java предпочтительнее делать так:

тип_массива[] название_переменной = new тип_массива[размер_массива];

Тип массива может быть любым (int, Integer, String, Date, byte, char, Long и так далее).

Инициализация массива по умолчанию

Объявим массив типа int из 10 элементов:

int[] marks = new int[10];

При подобной инициализации все элементы массива будут иметь значение по умолчанию. Для int это 0; для float и double — 0.0; для char — \0; для boolean — false, а для String и любого другого класса это null.

Размер массива (длина, протяжённость) определяется при объявлении, а изменить его можно только пересоздав массив.

Доступ к элементам массива

Начнём с одномерного массива. Каждый элемент в нём хранится под своим индексом.

Важно помнить, что в Java нумерация элементов массива начинается с 0. Поэтому индекс первого элемента равен 0, а у последнего определяется размером массива минус один.

Для доступа к элементу массива указывают имя массива и номер ячейки в квадратных скобках. Например, обратимся к первому элементу массива и выведем его значение:

int[] marks = new int[10];
System.out.println(marks[0]);

--OUTPUT> 0

В консоли мы получим число 0. Почему ноль — читайте выше, в пункте про инициализацию по умолчанию.

Заполним элементы массива. Для этого обратимся к каждому по индексу и присвоим значения с помощью оператора «=»:

int[] marks = new int[10];
marks[0] = 5;
marks[1] = 3;
marks[2] = 5;
marks[3] = 3;
marks[4] = 4;
marks[5] = 4;
marks[6] = 3;
marks[7] = 2;
marks[8] = 5;
marks[9] = 4;

Инициализация массива на этапе объявления

Теперь у нас есть массив, куда мы записали оценки десяти учеников. С этим уже удобнее работать, чем объявлять 10 переменных, но можно записать ещё короче:

int[] marks = new int[] {5, 3, 5, 3, 4, 4, 3, 2, 5, 4};

Мы опустили размер массива, поставили фигурные скобки после квадратных и перечислили все значения через запятую. Размер массива теперь определяется числом элементов в фигурных скобках (в нашем случае их тоже 10).

Но нет предела совершенству:

int[] marks = {5, 3, 5, 3, 4, 4, 3, 2, 5, 4};

После знака «=» остались только фигурные скобки с перечислением значений через запятую.

Обход одномерного массива

У массива в Java есть специальное поле length. Значение в нём нельзя изменить. Оно возвращает число элементов массива:

int[] marks = {5, 3, 5, 3, 4, 4, 3, 2, 5, 4};
System.out.println("Всего оценок: " + marks.length);

--OUTPUT> Всего оценок: 10

А раз мы знаем длину массива и что все его ячейки упорядочены, то остаётся обратиться к ним по очереди — в цикле:

int[] marks = {5, 3, 5, 3, 4, 4, 3, 2, 5, 4};

for (int i = 0; i < marks.length; i++) {
   System.out.printf("Ученик №%d: оценка %d%n", (i + 1), marks[i]);
}

--OUTPUT> Ученик №1: оценка 5
--OUTPUT> Ученик №2: оценка 3
--OUTPUT> Ученик №3: оценка 5
--OUTPUT> Ученик №4: оценка 3
--OUTPUT> Ученик №5: оценка 4
--OUTPUT> Ученик №6: оценка 4
--OUTPUT> Ученик №7: оценка 3
--OUTPUT> Ученик №8: оценка 2
--OUTPUT> Ученик №9: оценка 5
--OUTPUT> Ученик №10: оценка 4

С помощью счётчика в цикле for мы получаем индекс каждого элемента.

Напомним! Счётчик должен стартовать с 0, так как нумерация в массиве тоже начинается с 0.

И цикл будет продолжаться «пока счётчик меньше размера массива», а раз индекс последнего элемента на один меньше их количества, то выхода за границы массива в нашем цикле не произойдёт.

Вот ещё пример:

int[] marks = {5, 3, 4};
String[] names = {"Вася", "Петя", "Маша"};

for (int i = 0; i < marks.length; i++) {
   System.out.printf("%s получает оценку %d%n", names[i], marks[i]);
}

--OUTPUT> Вася получает оценку 5
--OUTPUT> Петя получает оценку 3
--OUTPUT> Маша получает оценку 5

Массив можно обойти и в цикле foreach:

int[] marks = {5, 3, 5, 3, 4, 4, 3, 2, 5, 4};

for (int mark : marks) {
   System.out.printf("Оценка %d%n", mark);
}
--OUTPUT> Оценка 5
--OUTPUT> Оценка 3
--OUTPUT> Оценка 5
--OUTPUT> Оценка 3
--OUTPUT> Оценка 4
--OUTPUT> Оценка 4
--OUTPUT> Оценка 3
--OUTPUT> Оценка 2
--OUTPUT> Оценка 5
--OUTPUT> Оценка 4

И в обратном порядке:

int[] marks = {5, 3, 5, 3, 4, 4, 3, 2, 5, 4};
for (int i = marks.length - 1; i >= 0; i--) {
   System.out.printf("Ученик №%d: оценка %d%n", (i + 1), marks[i]);
}

Здесь счётчик стартует со значения на один меньше размера массива, и цикл продолжается «пока счётчик не меньше 0».

Можем пройтись и только по элементам с чётными индексами:

int[] marks = {5, 3, 5, 3, 4, 4, 3, 2, 5, 4};
for (int i = 0; i < marks.length; i += 2) {
   System.out.printf("Ученик №%d: оценка %d%n", (i + 1), marks[i]);
}

А вот как заполнить массив случайными значениями:

int[] marks = new int[10];
Random random = new Random();
for (int i = 0; i < marks.length; i ++) {
   marks[i] = 2 + random.nextInt(4);
}

N-мерные массивы

Размерность массива определяется тем, сколько индексов нужно, чтобы однозначно указать на элемент в массиве.

Массивы бывают одномерными (векторы), двумерными (матрицы), трёхмерными и так далее. То есть можно создавать не просто массивы, но и массивы массивов, а также массивы массивов массивов и так далее.

Рассмотрим вариант с двумерным массивом. Остальные многомерные массивы создаются похоже.

Объявление двумерного массива

Чтобы создать двумерный массив, укажем его размеры в квадратных скобках:

int[][] mas = new int[3][4];

Доступ к элементу подобного массива выглядит так:

int[][] mas = new int[3][4];
mas[0][1] = 2;

Мы присвоили значение 2 элементу с индексами [0,1].

Для простоты представим двумерный массив в виде таблицы. Вот как выглядит наш массив (столбцы — это первый индекс в квадратных скобках, а строки — второй):

[0,0] = 0[1,0] = 0[2,0] = 0
[0,1] = 2[1,1] = 0[2,1] = 0
[0,2] = 0[1,2] = 0[2,2] = 0
[0,3] = 0[1,3] = 0[2,3] = 0

Несложно представить двумерный массив таблицей, а трёхмерный — кубом, но вот с массивами большей размерности так уже не получится.

Массивы внутри массива в Java могут быть разной длины. Зададим двумерный массив, где размер третьего массива (по индексу второго) равен двум элементам, а размер всех остальных — трём:

int[][] mas2 = {{1, 3, 5}, {1, 3, 4}, {1, 3}};

Как помним, размер массива нам не изменить, но мы можем присвоить новый массив элементу с нужным индексом.

Если мы объявляем двумерный массив так:

int[][] mas = new int[3][4];

то размер каждого вложенного массива будет равен четырём элементам.

А теперь заменим массив под индексом 1 (длиной в четыре элемента) массивом из двух элементов:

int[][] mas = new int[3][4];
mas[1] = new int[2];

Как видно из примера, мы можем обращаться к внутренним массивам нашего двумерного массива, а не только к значениям в этих массивах.

Проверим, что размер массива под индексом 1 теперь равен двум элементам. Для этого используем цикл с выводом в консоль:

for (int i = 0; i < mas.length; i++) {
   System.out.printf("Индекс массива в двумерном массиве: %d; длина массива: %d%n", i, mas[i].length);
}

--OUTPUT> Индекс массива в двумерном массиве: 0; длина массива: 4
--OUTPUT> Индекс массива в двумерном массиве: 1; длина массива: 2
--OUTPUT> Индекс массива в двумерном массиве: 2; длина массива: 4

Для обхода элементов двумерного массива применяем уже два цикла:

for (int i = 0; i < mas.length; i++) {
   for (int j = 0; j < mas[i].length; j++) {
       System.out.println(mas[i][j]);
   }
}

Квадратная матрица и куб

Если длины измерений (строк и столбцов) двумерного массива равны, то он называется квадратной матрицей.

Пример создания квадратной матрицы:

int[][] mas = new int[3][3];

Поворот квадратной матрицы на 90 градусов по часовой стрелке:

int[][] mas = {
       {1, 2, 3},
       {4, 5, 6},
       {7, 8, 9}};
for (int i = 0; i < mas.length / 2; i++) {
   int n = mas.length - 1;
   for (int j = i; j < mas.length - i - 1; j++) {
       int temp = mas[i][j];
       mas[i][j] = mas[n - j][i];
       mas[n - j][i] = mas[n - i][n - j];
       mas[n - i][n - j] = mas[j][n - i];
       mas[j][n - i] = temp;
   }
}

И против часовой:

int[][] mas = {
       {1, 2, 3},
       {4, 5, 6},
       {7, 8, 9}};

for (int i = 0; i < mas.length / 2; i++) {
   int n = mas.length - 1;
   for (int j = i; j < mas.length - i - 1; j++) {
       int temp = mas[i][j];
       mas[i][j] = mas[j][n - i];
       mas[j][n - i] = mas[n - i][n - j];
       mas[n - i][n - j] = mas[n - j][i];
       mas[n - j][i] = temp;
   }
}

Пример создания трёхмерного массива (кубический массив):

int[][][] mas = {{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, {{10, 11, 12}, {13, 14, 15}, {16, 17, 18}}, {{19, 20, 21}, {22, 23, 24}, {25, 26, 27}}};

Классы и методы работы с массивами

Здорово облегчает работу с массивами (вроде сортировки и поиска) класс Arrays. Полная документация по нему здесь.

Например, вывести массив в консоль помогает метод Arrays.toString:

int[] mas = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(mas));

А можно сделать из массива stream и работать со stream api:

int[] mas = {1, 2, 3, 4, 5, 6};
Arrays.stream(mas);

Чтобы скопировать один массив в другой, есть метод System.arraycopy. Заменим кусок одного массива частью другого:

int[] mas = {1, 2, 3, 4, 5, 6};
int[] mas2 = new int[2];
System.arraycopy(mas, 3, mas2, 0, 2);
System.out.println(Arrays.toString(mas2));

Из массива mas мы копируем элементы в массив mas2, начиная с индекса под номером 3. Копируем два элемента, поэтому в массиве mas2 окажутся числа 4 и 5.

Подытожим

  • У массива есть имя, тип [элементов] и размер.
  • Размер задаётся целочисленным значением, изменить его нельзя.
  • Доступ к элементам происходит по их индексам.
  • Нумерация в массиве начинается с 0.
  • При создании массива с помощью new его ячейки заполняются значением по умолчанию.

Курс

Профессия Java-разработчик PRO


Вы с нуля освоите востребованный язык программирования, научитесь создавать качественные приложения под разные платформы и станете ценным Java-специалистом уровня middle.

Понравилась статья?
Да