«1. Обзор

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

2. Массивы Java и ArrayList

Массив Java — это базовая структура данных, предоставляемая языком. Напротив, ArrayList является реализацией интерфейса List, поддерживаемой массивом, и предоставляется в Java Collections Framework.

2.1. Доступ к элементам и их изменение

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

System.out.println(anArray[1]);
anArray[1] = 4;

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

int n = anArrayList.get(1);
anArrayList.set(1, 4);

2.2 . Фиксированный и динамический размер

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

Поскольку массив Java имеет фиксированный размер, нам нужно указать размер при его создании. Невозможно увеличить размер массива после его создания. Вместо этого нам нужно создать новый массив с измененным размером и скопировать все элементы из предыдущего массива.

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

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

Операция добавления имеет постоянную амортизированную временную стоимость. Другими словами, добавление n элементов в ArrayList требует O(n) времени.

2.3. Типы элементов

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

Когда мы вставляем элементы с примитивными типами данных в ArrayList, компилятор Java автоматически преобразует примитивный тип данных в соответствующий класс-оболочку объекта.

Давайте теперь посмотрим, как добавлять и вставлять элементы в массивы Java и ArrayList.

3. Добавление элемента

Как мы уже видели, массивы имеют фиксированный размер.

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

Давайте посмотрим на его реализацию на Java без использования каких-либо вспомогательных классов:

public Integer[] addElementUsingPureJava(Integer[] srcArray, int elementToAdd) {
    Integer[] destArray = new Integer[srcArray.length+1];

    for(int i = 0; i < srcArray.length; i++) {
        destArray[i] = srcArray[i];
    }

    destArray[destArray.length - 1] = elementToAdd;
    return destArray;
}

В качестве альтернативы, класс Arrays предоставляет вспомогательный метод copyOf(), который помогает создать новый массив большего размера и скопировать все элементы из старого массива:

int[] destArray = Arrays.copyOf(srcArray, srcArray.length + 1);

Создав новый массив, мы можем легко добавить в него новый элемент:

destArray[destArray.length - 1] = elementToAdd;

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

anArrayList.add(newElement);

4. Вставка элемента по индексу

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

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

Кроме того, нам нужно сдвинуть все элементы, идущие после указанного индекса, на одну позицию вправо:

public static int[] insertAnElementAtAGivenIndex(final int[] srcArray, int index, int newElement) {
    int[] destArray = new int[srcArray.length+1];
    int j = 0;
    for(int i = 0; i < destArray.length-1; i++) {

        if(i == index) {
            destArray[i] = newElement;
        } else {
            destArray[i] = srcArray[j];
            j++;
        }
    }
    return destArray;
}

Однако класс ArrayUtils дает нам более простое решение для вставки элементов в массив:

int[] destArray = ArrayUtils.insert(2, srcArray, 77);

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

«Метод insert() возвращает новый массив, содержащий большее количество элементов, с новым элементом по указанному индексу и всеми оставшимися элементами, сдвинутыми на одну позицию вправо.

Обратите внимание, что последний аргумент метода insert() является переменным аргументом, поэтому мы можем вставить любое количество элементов в массив.

Используем его для вставки трех элементов в srcArray, начиная со второго индекса:

int[] destArray = ArrayUtils.insert(2, srcArray, 77, 88, 99);

Остальные элементы будут сдвинуты на три позиции вправо.

Более того, для ArrayList это можно сделать тривиально:

anArrayList.add(index, newElement);

ArrayList сдвигает элементы и вставляет элемент в нужное место.

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

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

Как всегда, полный исходный код рабочих примеров доступен на GitHub.