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 .