Что это? Массивы в Java – это своего рода хранилища, куда помещаются однотипные переменные. В одной такой камере хранения может содержаться только один тип: числа, строки, объявленные самостоятельно.
Как работать? Первым шагами в работе с массивами в Java будут их объявление и создание. Также необходимо понимание типов данных, длины массива.
В статье рассказывается:
- Что собой представляют массивы в Java
- Объявление переменной массива в Java
- Создание массива в Java
- Типы данных массива в Java
- Длина массива в Java
- Вывод массива в Java
- Насколько быстро работают массивы в Java
-
Пройди тест и узнай, какая сфера тебе подходит:
айти, дизайн или маркетинг.Бесплатно от Geekbrains
Что собой представляют массивы в Java
Массивы Java образно можно сравнить с ячейками в камере хранения, в каждой из которых находится какой-то объект «Багаж» (всем ячейкам присвоен порядковый номер). Или же с винной картой: каждый напиток имеет свой номер, поэтому, делая заказ, достаточно назвать официанту цифру, которой обозначено приглянувшееся вино.
Аналогию также можно провести со списком студентов, которые обучаются в одной группе. Логично, что открывать данный список будет студент с фамилией «Андреев», а завершать – «Яковлев». Еще один пример – список пассажиров, заявленных на рейс: за каждым закреплено определенное место в салоне самолета.
Данные, необходимые для корректной работы программы, сохраняются с помощью различных переменных. В частности, если необходимо сохранить ник игрока, применяется переменная String name, если целочисленное значение – int number и т.д. Отдельные переменные используются в том случае, когда значений не так много или их количество известно заранее.
Однако, более распространены ситуации, когда в программе одновременно задействованы несколько чисел (например, десять). Или же количество значений становится известно только в тот момент, когда пользователи запускают приложение и вводят данные для авторизации. К тому же, в игре каждый раз могут принимать участие разное количество игроков, число которых устанавливается на момент запуска. Поскольку точное количество значений – величина неизвестная, воспользоваться отдельными переменными не получится.
Это связано с тем, что в этом случае программный код будет громоздким и узконаправленным. А еще возможности для его использования будут крайне ограничены, поскольку не получится использовать цикл для автоматизированной обработки данных.
В подобных ситуациях кодеры применяют особые структуры данных – массивы. Они дают возможность хранить в одном месте однотипные данные. Это, в свою очередь, максимально облегчает обработку информации. В языке программирования Java массивы используются очень часто.
В частности, массив целых чисел Java, как следует из названия, будет содержать только целочисленные значения (к примеру, int). Массив строк Java – исключительно строки. А массив элементов класса Dog будет включать только объекты Dog. Иными словами, создавая код на Java, нельзя в первую ячейку массива поместить целое число, во вторую – String, в третью – «собаку» и т.д.
Объявление переменной массива в Java
Чтобы выполнять операции с массивом, нужен доступ. Для этого необходимо объявить переменную, которая позволит обращаться к определенным ячейкам массива – достаточно будет просто указать номер (индекс) интересующей ячейки.
Например:
double[] numbers;
char[] letters;
int[] ids;
входят в ТОП-30 с доходом
от 210 000 ₽/мес
Скачивайте и используйте уже сегодня:
Топ-30 самых востребованных и высокооплачиваемых профессий 2023
Поможет разобраться в актуальной ситуации на рынке труда
Подборка 50+ бесплатных нейросетей для упрощения работы и увеличения заработка
Только проверенные нейросети с доступом из России и свободным использованием
ТОП-100 площадок для поиска работы от GeekBrains
Список проверенных ресурсов реальных вакансий с доходом от 210 000 ₽
Эти переменные имеют имя и тип данных, поэтому в Java они создаются по аналогии со всеми остальными. При этом обязательно использовать квадратные скобки [], которые ставятся после типа данных, которые хранятся в массиве. Стоит иметь в виду, что перед [] пробел не нужен. Такие скобки поясняют, что переменная предназначена для массива Java.
Квадратные скобки могут размещаться еще несколькими способами. Однако, вариант, рассмотренный выше, наиболее популярен среди кодеров. К тому же, [] – часть типа массива, поэтому логично, что они должны быть рядом с обозначением типа элементов, которые хранятся в этом массиве.
Могут встретится следующие варианты оформления:
- наиболее предпочтительный – int[] arr;
- int arr[];
- int [] arr;
- int arr [];
Поскольку синтаксис языков Java и С/С++ схож, в Java допускается использование нескольких вариантов постановки []. Тем не менее, правило хорошего тона – придерживаться общепринятого или корпоративного стиля. Нельзя сочетать несколько способов написания в одном исходном коде.
Поскольку элементов массива Java огромное множество, для объявления переменной можно использовать:
- имена существительные во множественном числе (к примеру, cats, cars, resumes, playerAttempts);
- местоимения (в частности, allNumbers, myBooks);
- имена прилагательные (например, physicalConstants).
Еще несколько вариантов:
String[] fullNames;
Player[] players;
short[] nums;
В массиве Java могут храниться значения как примитивных, так и ссылочных типов. Массив и сам по себе является примером ссылочного типа данных. Первая строка содержит переменную массива строк, вторая – массива игроков, третья – переменную, которая позволяет хранить примитивные целочисленные значения.
Создание массива в Java
Как создать массив в Java? При помощи ключевого слова new (обязательно необходимо указать его размерность и тип):
int[] array = new int[10];
Подобную запись необходимо читать справа налево, а именно:
- оператор new выделяет в памяти (heap/куче) пространство для хранения десяти элементов типа int;
- после этого он возвращает ссылку, которая будет храниться в стеке, в начало области памяти (совпадает с первым значением), предназначенной под массив;
- ссылка перемещается в переменную array, которая обладает таким же типом, как и массив.
Не стоит забывать о том, что после того, как массив будет создан, его размер (длину) изменить не получится.
Ниже рассмотрен пример массива Java со ссылочным типом данных String:
String[] strings = new String[4];
Это то же самое, что и
String[] strings;
strings = new String[4];
Скачать файлОпытные разработчики рекомендуют без особой необходимости не использовать разные строки для объявления переменной и создания массива. Во-первых, увеличивается объем исходного кода. Во-вторых, многих программистов подобная запись приводит в замешательство.
Типы данных массива в Java
В методичках, предназначенных для тех, кто изучает Java, указано, что массив представляет собой объект («An object is a class instance or an array»). Однако, несмотря на это, у массива нет класса, который описывал бы его.
Тип массива не тождественен классу (к примеру, int). Тем не менее, у него есть класс, который ассоциируется с ним. Его в автоматическом режиме создает виртуальная машина — Java Virtual Machine (JVM). Поскольку этот класс неявно наследуется от java.lang.Object, можно использовать практически все его методы (за исключением clone) и интерфейсы (Cloneable и Serializable). При этом разработчик не имеет доступа к коду (то есть посмотреть его не получится).
Ассоциируемые классы есть у каждого типа данных, которые хранятся в массиве. В частности, они создаются для boolean[], Player[], String и т.д. Именно эти классы представляют собой реальные типы массивов. С помощью рефлексии можно узнать их названия, а также настоящий тип массива, его суперкласс (от которого он наследуется) и список доступных методов массива Java.
Читайте также!
После того, как создан пустой массив (нулевой длины) и объявлены переменные, обязательно необходимо выполнить импорт java.lang.reflect.Method:
int[] arr = {};
System.out.println(«Тип массива — » + arr.getClass());
System.out.println(«Суперкласс типа массива — » + arr.getClass().getSuperclass());
System.out.println(«Доступные методы:»);
for (Method m : arr.getClass().getMethods()) {
System.out.println(m.getName());
}
Что показывает этот код:
- [I – это сигнатура типа (класса, который Java Virtual Machine создает во время выполнения) для объекта «массив с элементами типа int» (это настоящий тип данных массива, как объекта);
- [ указывает на то, что это – одномерный массив;
- I – показатель того, что он содержит целые числа;
- имя суперкласса, которое записано с на основе его полного имени – java.lang.Object.
Сигнатуры типов могут иметь разный формат:
[B — byte
[C — char
[D — double
[F — float
[I — int
[J — long
[S — short
[Z — boolean
[L — любой объект
Таким образом, тип массива и тип элементов, которые в нем хранятся, – это формально не одно и то же. В рассмотренном примере тип массива – это тип [I, а тип хранимых значений – int.
на обучение «Программист Java» до 24 ноября
Еще одно подтверждение того факта, что Object представляет собой суперкласс для массивов:
Object obj = new int[]{3, 6, 9};
int[] arr = (int[]) obj;
System.out.println(obj);
System.out.println(arr);
В первой строке объявлен и инициализирован массив Java, а ссылка на него присвоена переменной типа Object. И это сделано преднамеренно. Во второй строке Object приводится к типу int[]. В результате – ссылки обеих переменных указывают на один и тот же массив.
Результат данного кода:
[I@2f490758
[I@2f490758
Кодеры, работающие с Java, должны знать, что в случае, если попробовать вывести значение объекта (например, в println), записав его имя в метод в качестве аргумента, будет неявно вызван метод toString(). Массивы его не переопределяют – у них отсутствует собственная реализация данного метода. Поэтому применяется реализация по умолчанию, которая записана в классе Object.
Этот метод возвращает строку, которая записывается с помощью такого кода:
getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
Данная строка состоит из трех частей: имени класса – [I), разделителя в виде @ и шестнадцатеричного представления хеш-кода объекта.
В коде, рассмотренном выше, одну и ту же ссылку на массив хранят одновременно две переменные. При этом количество переменных, которые могут указывать на один массив, не ограничено.
Еще один пример массива Java. Для начала необходимо создать массив с нулевой длиной.
String[] array1 = {};
char[] array2 = new char[0];
Пустой массив – это объект, который обладает заголовком (Object header) и размером. Однако, отсутствует пространство в памяти, выделенное для элементов массива Java. Ссылка на подобный массив сохраняется в переменную и работает без нареканий.
При этом такой массив не равен null:
short[] array3 = null;
Null, в свою очередь, подразумевает, что отсутствует указатель на объект.
Длина массива в Java
Длина массива не обозначается при инициализации в момент объявления. Компилятор сам посчитает ее на основе количества значений, указанных в выражении.
Чтобы немного облегчить задачу, можно использовать статический метод arraycopy из утилитарного класса System. А именно:
System.arraycopy(src, srcPos, dest, destPos, length);
Где:
- src — старый массив;
- srcPos — позиция в старом массиве, с которой начинают чтение;
- dest — новый массив;
- destPos — позиция в новом массиве, с которой начинают запись;
- length — количество элементов, которые надо прочитать из старого массива.
Данный код позволяет сделать массив длиннее:
double[] values = new double[2];
values[0] = 1.0;
values[1] = 1.5;
double[] tmpValues = new double[3];
System.arraycopy(values, 0, tmpValues, 0, values.length);
values = tmpValues;
Для того, чтобы определить длину массива Java, необходимо прочитать значение переменной length, которая ассоциирована с ним.
int arrayLength = myFancyArray.length;
System.out.printLn(arrayLength);
Значение длины потребуется для работы с циклом for:
double[] myFancyArray = new double[5];
for (int i = 0; i < myFancyArray.length; i++) {
myFancyArray[i] = i * 2;
}
Вывод массива в Java
Важно разобраться, как выводить массивы Java. Опытные кодеры рекомендуют использовать оператор цикла for:
String[] weekDays = {“Понедельник”, “Вторник”, “Среда”, “Четверг”, “Пятница”, “Суббота”, “Воскресенье”};
for (int i = 0; i < weekDays.length; i++) {
System.out.println(weekDays[i]);
}
Читайте также!
Те, кто пользуется версией Java старше 1.6, могут применять оператор foreach:
String[] weekDays = {“Понедельник”, “Вторник”, “Среда”, “Четверг”, “Пятница”, “Суббота”, “Воскресенье”};
for (String weekDay: weekDays) {
System.out.println(weekDay);
}
String[] weekDays = {“Понедельник”, “Вторник”, “Среда”, “Четверг”, “Пятница”, “Суббота”, “Воскресенье”};
Arrays.stream(weekDays).forEach(weekDay ->
System.out.println(weekDay)
);
Насколько быстро работают массивы в Java
Чаще всего массив Java – это быстрая структура данных. Чтобы определить скорость массива, необходимо иметь представление о сложности алгоритмов (Big O Notation).
Обычно Big O Notation называют «О большое». Этот способ, который пришел из теории алгоритмов, позволяет обозначить сложность алгоритма.
Каждый алгоритм обладает двумя параметрами:
- время выполнения (Time Complexity);
- расход памяти (Space Complexity).
Логично, что чем длиннее массив, тем больше времени и памяти требуется на его заполнение.
Время исчисляется в количестве операций, которые совершает алгоритм. Благодаря этому есть возможность абстрагироваться от того факта, что «железо» влияет на скорость работы алгоритма.
К примеру, Time Complexity для поиска числа в массиве можно обозначить O(n), где n — это число ячеек в массиве Java. Чем больше количество ячеек, тем дольше работает алгоритм. Иными словами, выполняется большее количество итераций массива (n — максимальное число операций). В связи с тем, что поиск осуществляется в линейном порядке, ячейки перебираются поочередно. Подобный алгоритм является линейным.
Чтобы доступ к элементам массива Java был проще, в памяти они находятся в едином блоке.
В случае если номер ячейки известен, алгоритм обладает константным временем – O(1). Оно постоянно и не зависит от каких-либо факторов. При этом доступ к ячейкам происходит моментально (размер массива не имеет значения).
Длина массива – это стабильная величина, которая возникает в момент создания массива и хранится в его заголовке. Java Virtual Machine понимает, что данное значение неизменно, поэтому его не нужно вычислять, а можно просто взять из заголовка. Именно поэтому такой тип операции чтения максимально быстрый – он выполняется за константное время O(1).