Рубріки: ОсновыТеория

Массивы в Java: что это такое и как с ними работать

Сергій Бондаренко

Что такое массив?

В программировании часто работают с такой математической структурой как массив. В языке Java он рассматривается как некая группа элементов одного типа. 

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

Поскольку массив в Java является объектом, для его создания используется привычный способ: задается переменная (под именем которой мы будем подразумевать сам массив, хотя на самом деле она хранит лишь ссылку на него), а затем с помощью оператора new описываем структуру массива. 

Важная характеристика массива — его размерность.

Размерность — это количество индексов, необходимых для обращения к элементу массива. Доступ к любому компоненту массива осуществляется при помощи идентификатора, который называется индексом элемента.

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

Важно: в Java-массиве нельзя смешивать типы полей.

Java-массив

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

Команда для задания массива выглядит так:

типэлементов[] имя_переменной;

или так:

типэлементов имя_переменной[];

Обе записи — равнозначны. 

Процесс генерирования массива и запись ссылки на него в переменную выглядит так:

типэлементов[] переменная;

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

Для обеих команд допускается более краткая форма:

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

Рассмотрим общие формы для объявления одномерного массива.

Объявление массива Пример Комментарий
type variable_name [] int anArray [] Java-стиль
type [] variable_name int [] anArray Стиль, перекочевавший в Java из языка программирования С

При использовании такого объявления мы должны знать, что фактического массива пока не существует. Тут мы просто отправляем сообщение компилятору, о том, что поле anArray когда-нибудь будет приспособлено под массив с целыми числами. Чтобы связать anArray с реальным целочисленным массивом, нужно объявить его с помощью ключевого слова new:

int[] anArray = new int[10];

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

Например:

int [] anArray; // объявление массива
anArray = new int [20]; // выделяем память для массива

Или:

int [] intArray = new int [20]; // объединяем объявление с выделением памяти

Примечание: ячейкам в массиве, выделенным при помощи ключевого слова new, будут автоматически присвоены значения: 0 (для числового типа), false (для логического) и null (для ссылок).

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

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

int[] highloadToday = new int[13];

Выведем на экран длину массива:

System.out.println(highloadToday.length);

В консоли отобразится 13.

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

double[] firstList = new double[10];

Как узнать длину массива

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

Как узнать длину массива

Чтобы узнать длину нашего массива, используем его свойство length. Например:

int[] anArray = new int[10]; // создаем целочисленный массив на 10 ячеек и присваиваем ему имя anArray
System.out.println(anArray.length); // выводим длину нашего массива

Инициализируем массив, работаем с его элементами

Теперь мы знаем, что такое массив, но как его использовать — пока непонятно. Как загружать в него информацию, а потом ее оттуда извлекать? Давайте разбираться.

В широком смысле массив — это самая важная структура данных в программировании. Сам компьютер — это не что иное, как набор массивов. Байт — это массив из восьми двоичных разрядов, а строка — это массив символов.

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

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

Теперь давайте выясним особенности работы с этой полезной штукой. При объявлении создается массив в каждой ячейке которого — данные по умолчанию (это мы разобрали). Чтобы записать туда необходимые нам данные, нужно провести обряд инициализации, то есть присвоить каждой ячейке определенное значение.

Например, создадим массив, содержащий в себе четыре стороны света, и заполним его значениями:

String[] sides  = new String[4]; /* объявленному массиву Java выделил память для четырех строк (по умолчанию их значение будет null, потому что String относится к ссылочному типу)*/sides[0] = "North"; /* Получив доступ к первой ячейке (с нулевым индексом), мы вписали туда  строковое значение  */sides[1] = "South"; // тоже самое мы проделываем с ячейкой под индексом 1
sides[2] = "West"; // 2
sides[3] = "East"; // 3

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

Теперь совместим инициализацию с объявлением:

String[] sides = new String[] {"North", "South", "West", "East"};

И уберем оператор new, тем самым упростив запись:

String[] sides = {"North", "South", "West", "East"};

Выводим массив в консоль

Есть несколько способов перебора массивов, один из них — циклический, например, с помощью цикла for:

String[] sides = new String[] {"North", "South", "West", "East"};
for (int i = 0; i < 4; i++) {
    System.out.println(sides[i]);
}

Выведет:

North
South
West
East

Многомерные Java-массивы

Массивы, у которых только один индекс называется одномерным, мы уже рассмотрели. Но в них можно помещать не только примитивные типы данных и ссылки на объекты, но и другие массивы. В таком случае их называют многомерными.

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

Структура многомерного массива в Java (здесь мы видим свободные места в кинотеатре)

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

0 — означает, что место доступно, 1 — что занято. Мы также могли бы добавить еще и 2 для зарезервированных мест и так далее. Но пока ограничимся более простым примером.

Java не предоставляет никакой специальной поддержки для многомерных массивов, но мы можем легко объявить их как массив массивов. Это будет выглядеть вот так:

int [] [] cinema = новый int [5] [5];

Первое число указывает количество столбцов, второе — количество строк. Все числовые массивы в Java автоматически инициализируются нулевыми значениями после объявления. Мы только что создали таблицу, полную нулей.

Теперь давайте заполним кинозал единицами, как на картинке выше. Для создания строки из единиц используем несколько циклов for. Чтобы открыть доступ к элементам 2D-массива, мы должны ввести координаты столбцов и строк:

cinema[2][2] = 1; // центр
for (int i = 1; i < 4; i++) { // четвертая строка
    cinema[i][3] = 1;
}
for (int i = 0; i < 5; i++) { // последняя строка
    cinema[i][4] = 1;
}

Нужно иметь в виду, что если мы запросим cinema.length, он будет содержать количество столбцов (длину внешнего массива, представляющего столбцы). Чтобы определить количество строк (длину внутреннего массива), необходимо запросить cinema [0].length. Обратите внимание, что для работы должен быть хотя бы один столбец.

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

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

Результат:

00000
00000
00100
01110
11111  

Иногда может быть полезно создать массив с большим количеством измерений. Например, трехмерный. Вернемся к примеру с кинотеатром. Теперь представим, что в нем несколько этажей. Схематично это будет выглядеть так:

3D-массив

Давайте создадим 3D-массив:

int [] [] [] cinemas = новый int [5] [5] [3]; 

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

cinemas[3][2][1] = 1; // кинотеатр на втором этаже, третий ряд, четвертое место 

В такой ситуации, если мы запросим cinemas[0][0].length, то получим количество этажей.

Работа с массивами

Продемонстрируем простейшие манипуляции с элементами массива:

public class Array
{
    public static void main(String[] args) {

        int[] a = new int[4];
        a[0] = 17; //Инициализация элементов массива
        a[1] = 15;
        a[2] = 8;
        a[3] = 8;
 
        String[] s = {"October", "November", "December"}; /* Инициализацию и объявление можно применять параллельно*/        String[] s2 = new String[]{"Highload", "Today"}; /*Иногда инициализация и объявление могут применяться вместе с оператором new */        s2[0] = "Highload - "; //Изменяем первый элемент массива
        System.out.println(s2[0] + s2[1]); // Отображение в консоли "Highload - Today"
        a[2] = 5; // Компоненты массива - переменные
        System.out.println(a[2]);
    }
}

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

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

 public static int linearSearch(int[] array, int elementWanted) {
    for (int i = 0; i < array.length; i++) {
        if (array[i] == elementWanted) {
            return i;
        }
    }
    return -1;
}

Если наш массив уже упорядочен, можем применить другой метод. Для поиска:

  • мы разделяем массив на равные части;
  • смотрим на «центральный элемент» с индексом middleIndex;
  • сравниваем с разыскиваемым элементом;
  • если есть совпадение — алгоритм завершаем.

Когда разыскиваемый элемент меньше «центрального элемента» мы забываем про правую часть массива, а иначе — про левую часть. Затем повторяем эти действия до обнаружения элемента или пока очередной отрезок не станет пустым. В том случае, если элемент не обнаружен, возвращается значение -1:

public static int binarySearch(int[] array, int elementWanted) {
        int firstIndex = 0;
        int lastIndex = array.length - 1;

        // условие прекращения (элемент не представлен)
        while (firstIndex <= lastIndex) {
            int middleIndex = (firstIndex + lastIndex) / 2;
            // если центральный элемент - целевой элемент, возвращаем его индекс
            if (array[middleIndex] == elementWanted) {
                return middleIndex;
            }

            // когда центральный элемент в массиве меньше
            // переводим индекс в middle+1, не рассматривая первую часть 

            else if (array[middleIndex] < elementWanted) {
                firstIndex = middleIndex + 1;
            }
            // если центральный элемент больше
            // переводим наш индекс в middle-1, не рассматривая первую часть 

            else if (array[middleIndex] > elementWanted) {
                lastIndex = middleIndex - 1;
            }
        }
        return -1;
    }

Сортировка массивов

Выполнять упорядочивание массива можно используя метод .sort() класса Arrays (не забываем в начале программы добавлять import java.util.Arrays;):

int[] highload = { 24, 7, 23, 6765, 95, 33 };
Arrays.sort(highload);
System.out.println(Arrays.toString(highload));// [7, 23, 24, 33, 95, 6765]

Более подробно о различных алгоритмах сортировки массивов можете почитать в статье «Методы сортировки и их реализация в Python». Несмотря на то, что мы писали в этой статье про Python, все алгоритмы актуальны и для Java. 

Преобразование массива к строке

Иногда может возникнуть необходимость преобразования массива к строке. Есть разные способы решения данной задачи. Например, обратиться к статическому методу join() класса String, который объединяет элементы массива. В этом примере элементы массива отделяются при помощи указанным параметром — разделителем:

String[] words = ["Highload", "Today"];

// Разделитель может быть пустой строкой
String.join("", words); // "HighloadToday"
String.join(", ", words); // "Highload, Today"

Java.util.Arrays: готовые решения для обработки массивов

Наиболее часто используемые операции по работе с java-массивами:

  • сортировка;
  • поиск нужного элемента;
  • преобразование массива в строку.

Одним из самых удобных способов решения такого рода задач является использование класса Arrays пакета java.util. Рассмотрим на примере их реализацию:

class Main {
    public static void main(String[] args) {
        int[] test = {1, 5, 4, 3, 7}; //объявление и инициализация массива
        System.out.println(test); //попытка вывода нашего массива в консоль (результат 16-ричное число)
        System.out.println(Arrays.toString(test)); //выводим в консоль массив при помощи метода toString и радуемся правильному результату
        Arrays.sort(test, 0, 4); //сортировка массива от 0-й до 4-й ячейки
        System.out.println(Arrays.toString(test)); //выводим результат сортировки
        int keyArray = Arrays.binarySearch(test, 8); // поиск keyArray - т.е. числа 8 в отсортированном массиве, метод binarySearch выдает индекс искомого элемента
        System.out.println(keyArray); //выводим в консоль этот индекс
System.out.println(Arrays.binarySearch(test, 0)); //пробуем найти элемент, отсутствующий в массиве и выводим результат в консоль
    }
}

Выведет:

[I@1540e19d
[1 , 5 , 4 , 3 , 7]
[1,  3,  4,  5,  7] 
3 
-1

Заключение

  • Массив — это объект-контейнер, содержащий в себе установленное при создании количество значений определенного типа, которое не может быть впоследствии изменено.
  • Нумерация элементов массива начинается с нуля.
  • Доступ к ячейкам массива легко получить по его индексу.
  • Наиболее удобные инструменты для обработки массивов предоставляет класс Java.util.Arrays.

Теперь вы можете самостоятельно управлять в языке Java таким важным математическим инструментом. Если вы желаете закрепить полученные знания, рекомендуем вам посмотреть видео, в котором подробно разобран ряд задач, связанных с одномерными и многомерными массивами в Java:

 

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023