W3docs

Массивы в Java

Объявляйте, инициализируйте и обращайтесь к элементам массивов Java — индексированных последовательностей значений одного типа фиксированного размера.

Массив в Java — это контейнер фиксированного размера, хранящий последовательность значений одного типа. Как только вы его создали, его длина больше не меняется, и каждая ячейка может хранить ровно одно значение — int, String, ссылку на любой объект, всё, что подходит под объявленный тип.

Массивы — это фундамент, на котором построены остальные коллекции Java (ArrayList, HashMap и им подобные). Они не так удобны, как эти классы более высокого уровня, но они быстры, предсказуемы, и вы будете встречать их повсюду — аргументы методов, возвращаемые значения, код, чувствительный к производительности.

Объявление массива

Тип массива — это тип элемента, за которым следует []:

int[] scores;       // an array of ints
String[] names;     // an array of String references
double[] prices;    // an array of doubles

Квадратные скобки могут стоять и после имени переменной — int scores[];, — но форма int[] scores встречается гораздо чаще и именно её вам следует использовать.

Объявление переменной ещё не создаёт массив; оно лишь даёт Java ячейку, которая может хранить ссылку на него. Эта ячейка изначально равна null.

Создание массива с помощью new

Чтобы действительно выделить массив, используйте new с длиной:

int[] scores = new int[5];

Это резервирует место для 5 значений int. Java инициализирует каждую ячейку значением по умолчанию для данного типа:

  • числовые типы → 0 (или 0.0)
  • booleanfalse
  • char' '
  • ссылочные типы → null

Поэтому scores сразу содержит {0, 0, 0, 0, 0}. Нет «неинициализированного» состояния — как только вы создали массив, у каждой позиции есть определённое значение.

Литералы массивов

Когда содержимое известно заранее, используйте литерал:

int[] scores = {90, 85, 73, 100, 62};
String[] colors = {"red", "green", "blue"};

Длина выводится из количества элементов. Эта форма допустима только в той же строке, что и объявление, — позже написать scores = {90, 85}; нельзя. Для этого используйте явную форму:

scores = new int[]{90, 85, 73, 100, 62};

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

Вы читаете и записываете элементы по индексу, начинающемуся с нуля, с помощью квадратных скобок:

int[] scores = {90, 85, 73, 100, 62};
System.out.println(scores[0]);   // 90
System.out.println(scores[4]);   // 62
scores[2] = 80;                  // replace 73 with 80

Допустимые индексы идут от 0 до length - 1. Индекс вне диапазона во время выполнения выбрасывает ArrayIndexOutOfBoundsException — Java не возвращает молча значение по умолчанию и не зацикливается.

Свойство length

У каждого массива есть открытое поле length, доступное только для чтения, которое сообщает его размер:

int[] scores = {90, 85, 73, 100, 62};
System.out.println(scores.length);   // 5

Обратите внимание, что это поле, а не метод — без скобок. Это одна из мелких особенностей Java: строки используют .length(), массивы используют .length. Они также ведут себя иначе, чем коллекции (list.size()). Эти формы легко перепутать; компилятор вам подскажет.

length фиксируется при создании. Чтобы «увеличить» массив, нужно выделить новый и скопировать — см. главу Копирование массивов.

Массивы хранят ссылки, а не копии

Когда тип элемента — объект, массив хранит ссылки, а не сами объекты:

String[] colors = {"red", "green", "blue"};
String first = colors[0];
// first and colors[0] both reference the same "red" string

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

Значения по умолчанию и null-массивы

Объявленная, но не присвоенная переменная массива равна null, и чтение .length или любого индекса на ней выбрасывает NullPointerException:

int[] data;            // not initialized
// System.out.println(data.length);  // would throw NullPointerException
data = new int[3];
System.out.println(data.length);     // 3

Пустой массив — длиной ноль — это вполне допустимый массив, и обычно именно он нужен для «пустого» возвращаемого значения, а не null:

int[] none = new int[0];
System.out.println(none.length);     // 0

Разобранный пример

java— editable, runs on the server

Что дальше

Вы умеете построить массив и обратиться к нему по индексу. Следующий шаг — итерация: посещение каждого элемента по очереди с помощью циклов по массивам, чтобы не выписывать scores[0], scores[1], scores[2] поодиночке.

Practice

Практика

What does new int[3] produce?