Рубрики
Без рубрики

Массивы на Java: Справочное руководство

Простое и полное справочное руководство по пониманию и использованию массивов на Java.

Автор оригинала: François Dupire.

Массивы на Java: Справочное руководство

1. Введение

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

Сначала мы увидим, что такое массив, а затем, как их использовать; в целом, мы будем охватывать, как:

  • Начать работу с массивами
  • Элементы чтения и записи массивов
  • Петля над массивом
  • Преобразование массивов в другие объекты, такие как Список или Потоки
  • Сортировка, поиск и комбинирование массивов

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

Во-первых, мы должны определить, что такое массив? По данным документация Java , массив объект, содержащий фиксированное количество значений одного и того же типа . Элементы массива индексируются, что означает, что мы можем получить к ним доступ с номерами ( индексы ).

Мы можем рассматривать массив как проумерный список ячеек, каждая ячейка является переменной, держащей значение. На Java проем начинается с 0.

Существуют примитивные массивы типов и массивы типа объектов. Это означает, что мы можем использовать массивы int, поплавок, boolean, … Но и массивы Строка, объект и пользовательские типы, а также.

3. Настройка массива

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

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

Давайте сначала с декларацией и инициализацией.

3.1. Декларация

Начнем с декларации. Существует два способа декларировать массив в Java:

int[] anArray;

или:

int anOtherArray[];

Первый из них используется более широко, чем второй .

3.2. Инициализация

Теперь пришло время посмотреть, как инициализировать массивы. Опять же Есть несколько способов инициализации массива. Мы увидим основные из них здесь, но эта статья охватывает массивы инициализации в деталях.

Начнем с простого способа:

int[] anArray = new int[10];

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

При использовании этого метода мы инициализируем каждый элемент к его стоимости по умолчанию , здесь 0 . При инициализации массива Объект , элементы нулевой по умолчанию.

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

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

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

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

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

Например, этот маленький фрагмент кода будет печатать 10 на консоли:

anArray[0] = 10;
System.out.println(anArray[0]);

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

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

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

5. Итерирование над массивом

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

Первый способ заключается в использовании для петля:

int[] anArray = new int[] {1, 2, 3, 4, 5};
for (int i = 0; i < anArray.length; i++) {
    System.out.println(anArray[i]);
}

Это должно печатать номера от 1 до 5 на консоли. Как мы видим, мы использовали длина свойство. Это государственная собственность дает нам размер массива.

Конечно, можно использовать другие механизмы цикла, такие как в то или делать в то время как . Но, что касается коллекций Java, можно цикл над массивами с помощью foreach петля:

int[] anArray = new int[] {1, 2, 3, 4, 5};
for (int element : anArray) {
    System.out.println(element);
}

Этот пример эквивалентен предыдущему, но мы избавились от шаблонного кода индексов. foreach цикл является вариантом, когда:

  • нам не нужно изменять массив (ввод другого значения в элемент не изменит элемент в массиве)
  • нам не нужны индексы, чтобы сделать что-то другое

6. Вараргс

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

void varargsMethod(String... varargs) {}

Этот метод может занять от 0 до произвольного числа Струнные Аргументы. Статья, охватывающая Вараргс можно найти здесь .

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

String[] anArray = new String[] {"Milk", "Tomato", "Chips"};
varargsMethod(anArray);

Будет вести себя так же, как:

varargsMethod("Milk", "Tomato", "Chips");

7. Преобразование массива в список

Arrays велики, но иногда это может быть более ручной, чтобы иметь дело с Список вместо. Здесь мы увидим, как превратить массив в Список .

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

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

List aList = new ArrayList<>();
for (int element : anArray) {
    aList.add(element);
}

Но есть и другой способ, немного более кратким:

Integer[] anArray = new Integer[] {1, 2, 3, 4, 5};
List aList = Arrays.asList(anArray);

Статический метод Arrays.asList занимает Вараргс аргумент и создает список с пройденных значений. К сожалению, этот метод имеет некоторые недостатки:

  • Невозможно использовать массив примитивных типов
  • Мы не можем добавить или удалить элементы из созданного списка, так как он бросит НеподдерживаемаяОперацияИсключение

8. От массива к потоку

Теперь мы можем преобразовывать массивы в списки, но с Java 8 у нас есть доступ к Поток API и мы, возможно, захотите превратить наши массивы в Поток . Java предоставляет нам Arrays.stream метод для этого:

String[] anArray = new String[] {"Milk", "Tomato", "Chips"};
Stream aStream = Arrays.stream(anArray);

При прохождении Объект массив к методу он вернет Поток соответствия типа (например, Поток для массива Интегер ). При прохождении примитивного он вернет соответствующую примитивную Поток .

Также можно создать поток только на подмножестве массива:

Stream anotherStream = Arrays.stream(anArray, 1, 3);

Это создаст Поток только “Томат” и “Чипс” Струны (первый индекс является инклюзивным, а второй – эксклюзивным).

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

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

Есть перегрузки для сортировки:

  • Массивы примитивного типа: которые сортируются в порядке возрастания
  • Объект массивы (эти Объект должны реализовать Сопоставимые интерфейс): которые сортируются в соответствии с естественным порядком (опираясь на сравнить метод из Сопоставимо)
  • Общие массивы: которые сортируются в соответствии с данным компаратор

Кроме того, можно сортировать только определенную часть массива (переход стартовых и конечных индексов к методу).

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

Давайте посмотрим, как все это работает через несколько примеров:

int[] anArray = new int[] {5, 2, 1, 4, 8};
Arrays.sort(anArray); // anArray is now {1, 2, 4, 5, 8}

Integer[] anotherArray = new Integer[] {5, 2, 1, 4, 8};
Arrays.sort(anotherArray); // anotherArray is now {1, 2, 4, 5, 8}

String[] yetAnotherArray = new String[] {"A", "E", "Z", "B", "C"};
Arrays.sort(yetAnotherArray, 1, 3, 
  Comparator.comparing(String::toString).reversed()); // yetAnotherArray is now {"A", "Z", "E", "B", "C"}

10. Поиск в массиве

Поиск массива довольно прост, мы можем цикл над массивом и искать наш элемент среди элементов массива:

int[] anArray = new int[] {5, 2, 1, 4, 8};
for (int i = 0; i < anArray.length; i++) {
    if (anArray[i] == 4) {
        System.out.println("Found at index " + i);
        break;
    }
}

Здесь мы искали номер 4 и нашли его на индексе 3.

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

К счастью, Java предоставляет нам Arrays.binarySearch метод. Мы должны дать ему массив и элемент для поиска.

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

Рассмотрим пример использования метода двоичного поиска:

int[] anArray = new int[] {1, 2, 3, 4, 5};
int index = Arrays.binarySearch(anArray, 4);
System.out.println("Found at index " + index);

Поскольку мы хранили номер 4 в четвертой ячейке, это вернет индекс 3 в результате. Обратите внимание, что мы использовали уже отсортированный массив.

11. Конкатенатные массивы

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

int[] anArray = new int[] {5, 2, 1, 4, 8};
int[] anotherArray = new int[] {10, 4, 9, 11, 2};

int[] resultArray = new int[anArray.length + anotherArray.length];
for (int i = 0; i < resultArray.length; i++) {
    resultArray[i] = (i < anArray.length ? anArray[i] : anotherArray[i - anArray.length]);
}

Как мы видим, когда индекс все еще меньше, чем длина первого массива, мы добавляем элементы из этого массива. Затем добавляем элементы из второго. Мы можем воспользоваться этой Arrays.setВсе метод, чтобы избежать написания цикла:

int[] anArray = new int[] {5, 2, 1, 4, 8};
int[] anotherArray = new int[] {10, 4, 9, 11, 2};

int[] resultArray = new int[anArray.length + anotherArray.length];
Arrays.setAll(resultArray, i -> (i < anArray.length ? anArray[i] : anotherArray[i - anArray.length]));

Этот метод установит весь элемент массива в соответствии с данной функцией. Эта функция связывает индекс с результатом.

Вот третий вариант слияния с массивами: System.arraycopy . Этот метод принимает источник массив , позиция источника, пункт назначения массив , должность назначения и int определение количества элементов для копирования:

System.arraycopy(anArray, 0, resultArray, 0, anArray.length);
System.arraycopy(anotherArray, 0, resultArray, anArray.length, anotherArray.length);

Как видим, мы копим первый массив, затем второй (после последнего элемента первого).

12. Заключение

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

Мы увидели, что Java предлагает множество методов для работы с массивами через класс утилиты Arrays. Существуют также классы утилит для управления массивами в библиотеках, таких как Apache Commons или Guava.

Полный код этой статьи можно найти на наш GitHub .