Вступление
В этом руководстве будут рассмотрены некоторые общие методы удаления элементов из массивов Java. Управление элементами массива - чрезвычайно распространенная задача, поскольку ее обсуждения можно найти на многих форумах, особенно на StackOverflow.
Вот список техник и методов, которые мы рассмотрим в этой статье:
Краткое описание массивов
Массивы - это структуры данных, распространенные во многих языках программирования. Каждый массив хранится в едином блоке памяти, что позволяет последовательно хранить и легко манипулировать элементами:
[Кредит: CodeForWin]{.small}
Элементы сохраняются последовательно один за другим. Когда кто-то хочет получить доступ к элементу по определенному индексу, арифметика указателей (которая является механизмом под капотом) позволяет быстро и эффективно получить любой конкретный элемент.
Если индекс запрошенного элемента равен 3
, базовый механизм просто
должен взять адрес памяти нулевого элемента и добавить в три раза
размер каждого элемента. Поскольку все элементы массива имеют одинаковый
размер, такие вычисления приводят непосредственно к элементу с индексом
3
. Кроме того, это происходит при O(1)
что означает, что это
максимально быстро.
Что затрудняет удаление элемента массива, так это тот факт, что все элементы хранятся последовательно в одном блоке памяти. Из-за особенностей размещения массива в памяти напрямую удалить элемент просто невозможно.
Вместо этого, чтобы «удалить» любой элемент, все последующие элементы нужно сдвинуть назад на одно место. Это создаст иллюзию, что определенный элемент был удален.
Использование двух массивов
Самый простой способ сделать это на чистом Java - создать новый массив на один элемент короче исходного и скопировать в него все элементы, кроме того, который мы хотели бы удалить:
int[] copy = new int[array.length - 1];
for (int i = 0, j = 0; i < array.length; i++) {
if (i != index) {
copy[j++] = array[i];
}
}
Здесь мы просто перебираем исходный массив и копируем элементы из исходного массива в новый массив, пропуская тот, который мы хотели бы удалить.
Теперь copy
массив состоит из:
10, 20, 30, 50, 60, 70, 80, 90, 100
ArrayUtils.remove ()
Если вы уже используете библиотеку Apache Commons, вы можете
использовать метод ArrayUtils.remove()
.
Прежде чем работать с Apache Commons, мы хотим добавить его в наш проект:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${version}</version>
</dependency>
Использовать метод очень просто. Мы просто предоставляем ему массив, из которого мы хотим удалить элемент, и его индекс:
int[] array = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int index = 3;
array = ArrayUtils.remove(array, index);
Затем он возвращает новый массив, который хранится в переменной array
10, 20, 30, 50, 60, 70, 80, 90, 100
Использование цикла for
Казалось бы, самый простой способ удалить элемент - выполнить итерацию
массива вручную с помощью цикла for
С другой стороны , в while
петли
также могут быть использованы , но for
гораздо больше подходит для
данного типа задач.
Скажем, мы хотим удалить третий элемент:
int[] array = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int index = 3;
Элемент, соответствующий индексу 3
равен 40
. Чтобы удалить этот
элемент, мы просто «сдвигаем» все элементы после него. Это означает, что
мы собираемся 40
и просто «переместить» их на одно место влево.
Поскольку невозможно просто переместить элемент, вместо этого мы копируем его значение. Последующие копии будут перезаписывать исходные значения, и результат будет таким, как если бы вся правая часть массива была сдвинута влево на единицу:
for (int i = index; i < array.length - 1; i++) {
array[i] = array[i + 1];
}
Если бы мы пошли и напечатали модифицированный массив, результат был бы следующим:
10, 20, 30, 50, 60, 70, 80, 90, 100, 100
Массивы имеют фиксированную длину. Из-за этого дублируется последний
элемент, 100
Используя один массив, невозможно удалить элемент, не
заполнив новый пробел каким-либо значением.
Вы можете переопределить его фиктивным значением, например -1
, но
это решение не очень верное. Это устраняется использованием двух
массивов .
System.arraycopy
Сокращенный способ сделать то же самое, что и раньше, но в одной строке
кода - это System.arraycopy()
:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
Метод принимает исходный массив и позицию, с которой начинается копирование. Он также принимает целевой массив и позицию, в которую следует начать копирование. Последний аргумент - это количество элементов, которые нужно скопировать из исходного массива.
arraycopy
обычно используется для копирования содержимого из
некоторого исходного массива в некоторый целевой массив. Хотя мы также
можем скопировать массив или его часть в себя. Это позволяет нам
сдвинуть его часть влево, как в прошлый раз:
int[] array = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int index = 3;
Чтобы удалить элемент, нам нужно написать всего одну строку кода:
System.arraycopy(array, index + 1, array, index, array.length - index - 1);
Метод скопирует все элементы из исходного массива ( array
), начиная с
одной позиции справа от index
. Элементы будут скопированы в один и
тот же массив ( array
), начиная с index
. Результатом будет
воспринимаемое смещение всех элементов вправо от элемента, который мы
хотели удалить.
Если бы мы распечатали результат, мы все равно увидели бы 100
по той
же причине, что и в предыдущем разделе. В следующем разделе мы покажем,
как полностью устранить эту проблему.
Заключение
В этом руководстве мы показали несколько способов удаления элементов массива. Некоторые из них бывают быстрыми и грязными, тогда как некоторые требуют дополнительных накладных расходов, таких как использование дополнительных библиотек. Всегда лучше подумать об этом заранее, чтобы понять, какой подход подходит для той или иной ситуации.
Список методов, показанных в этом руководстве, ни в коем случае не является исчерпывающим. Есть много способов проявить творческий подход в программировании, поэтому мы уверены, что вы сможете найти и другие интересные подходы для удаления элементов из массивов.