Глиф Учебники

Урок 6. Массивы

Курс «Java» · урок 6 из 10 · 4 минуты чтения

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

Создание массива

Есть два способа. Если значения известны сразу — перечислите их в фигурных скобках:

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

Если известен только размер — создайте массив через new:

Java
int[] counts = new int[10];

Квадратные скобки после типа значат «массив таких значений»: int[] — массив целых, String[] — массив строк. Новый массив заполнен значениями по умолчанию: 0 у чисел, false у boolean, null («ничего») у строк и других объектов. Размер массива после создания не меняется.

Элементы и длина

Java
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] marks = {5, 4, 3, 5, 4};
        System.out.println(marks.length);
        System.out.println(marks[0]);
        System.out.println(marks[marks.length - 1]);
        marks[2] = 5;
        System.out.println(Arrays.toString(marks));
    }
}
Вывод
5
5
4
[5, 4, 5, 5, 4]

Если вывести массив просто через System.out.println(marks), появится что-то вроде [I@1b6d3586 — тип и служебный номер объекта, а не элементы. Для вывода всегда нужен Arrays.toString.

Обращение к несуществующему индексу — marks[5] при длине 5 или marks[-1] — останавливает программу с ошибкой ArrayIndexOutOfBoundsException. Что с ней делать — в справке ArrayIndexOutOfBoundsException.

int[] marks = {5, 4, 3, 5, 4}; marks.length = 5 [-1] [0] [1] [2] [3] [4] [5] нет 5 4 3 5 4 нет marks[0] первый marks[marks.length - 1] последний marks[-1] и marks[5] → ArrayIndexOutOfBoundsException
У массива marks из пяти элементов индексы от 0 до 4: у первого элемента индекс 0, у последнего — marks.length - 1, а индексы −1 и 5 выходят за границы и дают ArrayIndexOutOfBoundsException.

Обход массива циклом

Обычный for со счётчиком даёт и индекс, и элемент. Если индекс не нужен, короче for-each — «для каждого элемента»:

Java
public class Main {
    public static void main(String[] args) {
        int[] temps = {-3, 2, 5, -1, 7, 8};
        int sum = 0;
        int max = temps[0];
        for (int t : temps) {
            sum += t;
            if (t > max) {
                max = t;
            }
        }
        System.out.println("Сумма: " + sum);
        System.out.println("Максимум: " + max);
        System.out.println("Среднее: " + (double) sum / temps.length);
    }
}
Вывод
Сумма: 18
Максимум: 8
Среднее: 3.0

for (int t : temps) читается так: «для каждого t из temps». На каждой итерации в t лежит очередной элемент. Менять элементы через t нельзя — это копия значения; для записи нужен цикл с индексом:

Java
for (int i = 0; i < temps.length; i++) {
    temps[i] = temps[i] * 2;
}

Максимум начинают искать с первого элемента, а не с нуля: если все числа отрицательные, ноль дал бы неверный ответ.

Ввод массива с клавиатуры

Сначала читают количество элементов, потом создают массив такого размера и заполняют его в цикле:

Java
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.nextInt();
        }
        Arrays.sort(a);
        System.out.println(Arrays.toString(a));
    }
}
Ввод
5
3 9 1 7 2
Вывод
[1, 2, 3, 7, 9]

Arrays.sort сортирует массив по возрастанию прямо на месте. Другие способы сортировки, в том числе по убыванию, — в справке Как отсортировать массив или список.

Копирование и сравнение

Переменная массива хранит не сами элементы, а ссылку на них. Присваивание копирует ссылку, а не массив:

Java
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3};
        int[] b = a;
        b[0] = 100;
        System.out.println(Arrays.toString(a));
        int[] c = Arrays.copyOf(a, a.length);
        c[1] = 200;
        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.toString(c));
    }
}
Вывод
[100, 2, 3]
[100, 2, 3]
[100, 200, 3]

После b = a обе переменные указывают на один и тот же массив, поэтому изменение через b видно и в a. Настоящую копию делает Arrays.copyOf. По той же причине a == c сравнивает ссылки, а не содержимое: сравнить элементы помогает Arrays.equals(a, c).

int[] b = a; b[0] = 100; a b 100 2 3 один массив на две переменные int[] c = Arrays.copyOf(a, a.length); c[1] = 200; a 100 2 3 c 100 200 3 два разных массива
После b = a обе переменные ссылаются на один массив, и запись 100 через b видна в a; Arrays.copyOf создаёт отдельный массив c, и 200 в c не меняет a.

Двумерные массивы

Таблица — это массив массивов: int[][]. Первый индекс — строка, второй — столбец.

Java
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[][] grid = {
            {1, 2, 3},
            {4, 5, 6}
        };
        System.out.println(grid.length);
        System.out.println(grid[0].length);
        System.out.println(grid[1][2]);
        System.out.println(Arrays.deepToString(grid));
    }
}
Вывод
2
3
6
[[1, 2, 3], [4, 5, 6]]

grid.length — число строк, grid[0].length — число столбцов в первой строке. Пустая таблица 3 на 4 создаётся так: new int[3][4]. Для обхода нужны два вложенных цикла: внешний по строкам, внутренний по столбцам.

grid [0] [1] [0] [1] [2] 1 2 3 4 5 6 grid[0].length = 3 столбца в строке 0 grid[1][2] = 6 строка 1, столбец 2 grid.length = 2 строки каждая строка — отдельный массив
Двумерный массив grid — массив из двух строк, каждая строка — отдельный массив из трёх чисел; первый индекс выбирает строку, второй — столбец, и в строке 1, столбце 2 лежит 6.

Если нужен массив, который растёт

Размер массива задаётся при создании. Если заранее неизвестно, сколько будет элементов, берите список ArrayList — он увеличивается сам при каждом добавлении. Как с ним работать — в справке ArrayList: список в Java.

Коротко

Проверьте себя

1. Какой индекс у последнего элемента массива a из 10 элементов?
2. Что лежит в элементах массива после new int[3]?
3. Как вывести элементы массива a одной строкой вида [1, 2, 3]?
4. После int[] b = a; b[0] = 7; что будет в a[0]?