Как удалить элемент из списка java
Перейти к содержимому

Как удалить элемент из списка java

  • автор:

Как удалить элемент из ArrayList при итерации?

Подвох в том, что итератор ArrayList , который используется в таком варианте цикла for , является fail-fast, то есть не поддерживает итерацию с параллельной модификацией. А параллельная модификация случается даже в одном потоке, что демонстрирует этот пример. Следующий шаг итератора после удаления элемента выбросит ConcurrentModificationException .

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

Единственный способ удалить элемент из коллекции при обходе, не получив при этом ConcurrentModificationException или неопределенное поведение – удалить с помощью remove() того же инстанса итератора. Вариант ListIterator поможет, если в теле цикла требуется и работа с индексами.

Некоторые коллекции, такие как CopyOnWriteArrayList и ConcurrentHashMap адаптированные под многопоточную среду и имеют fail-safe итераторы.

Как удалить элемент массива в Java?

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

Начнём с того, что в обычном массиве удаление осуществляется не очень удобно. То есть мы не можем просто взять и удалить ячейку из Java-массива. Зато можем обнулить значение этой ячейки.

 
public class Cat < private String name; public Cat(String name) < this.name = name; >public static void main(String[] args) < Cat[] cats = new Cat[3]; cats[0] = new Cat("Том"); cats[1] = new Cat("Вася"); cats[2] = new Cat("Мурка"); cats[1] = null; System.out.println(Arrays.toString(cats)); >@Override public String toString() < return "Cat'; > >
 
[Cat, null, Cat]

Итак, мы видим, что кот Вася благополучно обнулился. Однако при выполнении такой операции в Java-массиве остаётся «дыра», поскольку мы удаляем лишь содержимое ячейки, но не саму ячейку. То есть мы получаем пустую ячейку в середине массива, что не есть хорошо.

Что тут можно сделать? Например, переместить эту ячейку в самый конец массива, сдвинув другие элементы к началу:

 
public static void main(String[] args) < Cat[] cats = new Cat[4]; cats[0] = new Cat("Том"); cats[1] = new Cat("Вася"); cats[2] = new Cat("Мурка"); cats[3] = new Cat("Барсик"); cats[1] = null; for (int i = 2; i < cats.length-1; i++) < //выполняем перемещение элементов к началу, в результате чего пустая ячейка окажется в конце cats[i-1] = cats[i]; cats[i] = null; >System.out.println(Arrays.toString(cats)); >
 
[Cat, Cat, Cat, null]

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

Использование ArrayList

Если гора не идёт к Магомету, Магомет идёт к горе. Если мы не можем удалить элемент в обычном массиве, мы можем преобразовать массив в структуру, позволяющую удалять элементы. А потом преобразовать эту структуру обратно в массив.

Выполнить вышеописанную схему нам поможет java.util.List или ArrayList. Дело в том, что в ArrayList реализован специальный метод, позволяющий удалять элементы — remove. В общем виде всё выглядит так:

 
String[] array = new String[]; List list = new ArrayList<>(Arrays.asList(array)); list.remove("foo"); // Creates a new array with the same size as the list and copies the list // elements to it. array = list.toArray(new String[list.size()]); System.out.println(Arrays.toString(array)); //[bar, baz]

Давайте теперь рассмотрим работу метода remove на наших котах:

 
public static void main(String[] args) < ArrayListcats = new ArrayList<>(); Cat tom = new Cat("Том"); Cat vasya = new Cat("Вася"); Cat murka = new Cat("Мурка"); Cat barsik = new Cat("Барсик"); cats.add(tom); cats.add(vasya); cats.add(murka); cats.add(barsik); System.out.println(cats.toString()); cats.remove(1); System.out.println(cats.toString()); >

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

Тут следует отметить следующие особенности метода remove() : — он не оставляет так называемых «дыр» — в нём реализована логика сдвига элементов, если мы удаляем элемент из середины. Вот вывод предыдущего кода:

 
[Cat, Cat, Cat, Cat] [Cat, Cat, Cat]

То есть после удаления одного кота, остальные были передвинуты, и пробелов не осталось.

Кроме того, remove способен удалять объект не только по индексу, но и по ссылке:

 
public static void main(String[] args) < ArrayListcats = new ArrayList<>(); Cat tom = new Cat("Том"); Cat vasya = new Cat("Вася"); Cat murka = new Cat("Мурка"); Cat barsik = new Cat("Барсик"); cats.add(tom); cats.add(vasya); cats.add(murka); cats.add(barsik); System.out.println(cats.toString()); cats.remove(murka); System.out.println(cats.toString()); >
 
[Cat, Cat, Cat, Cat] [Cat, Cat, Cat]

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

Используем System.arraycopy

Мы можем просто создать копию исходного массива с помощью System.arraycopy(), удалив таким нехитрым способом соответствующий элемент:

 
int[] array = new int[] < 1, 2, 3, 4 >; // Original array. int[] result = new int[array.length - 1]; // Array which will contain the result. int index = 1; // Remove the value "2". // Copy the elements at the left of the index. System.arraycopy(array, 0, result, 0, index); // Copy the elements at the right of the index. System.arraycopy(array, index + 1, result, index, array.length - index - 1); System.out.println(Arrays.toString(result)); //[1, 3, 4]

Используем Apache Commons Lang

Последний способ, о котором стоит упомянуть, — применение библиотеки Apache Commons Lang и статического метода removeElement() класса ArrayUtils:

 
int[] array = new int[]; array = ArrayUtils.removeElement(array, 2); //remove first occurrence of 2 System.out.println(Arrays.toString(array)); //[1, 3, 4]

Apache Commons предоставляет нам библиотеку с именем org.apache.commons.lang3. Добавить библиотеку в ваш проект можно с помощью следующей maven-зависимости:

 
  org.apache.commons commons-lang3 3.0   

Данный пакет предоставляет класс ArrayUtils. Используя метод remove() этого класса, можно удалять элементы. Рассмотрим это на примере удаления повторяющихся элементов в массиве Java. Для обнаружения дублей надо сравнить каждый элемент Java-массива с оставшимися, для чего можно использовать 2 вложенных цикла.

 
import java.util.Arrays; import java.util.Scanner; import org.apache.commons.lang3.ArrayUtils; public class DeleteDuplicate < public static void main(String args[]) < Scanner sc = new Scanner(System.in); System.out.println("Enter the size of the array that is to be created::"); int size = sc.nextInt(); int[] myArray = new int[size]; System.out.println("Enter the elements of the array ::"); for(int i=0; iSystem.out.println("The array created is ::"+Arrays.toString(myArray)); for(int i=0; i > > System.out.println("Array after removing elements ::"+Arrays.toString(myArray)); > >

Вот, как это будет работать:

 
Enter the size of the array that is to be created :: 6 Enter the elements of the array :: 232 232 65 47 89 42 The array created is :: [232, 232, 65, 47, 89, 42] Array after removing elements :: [232, 65, 47, 89, 42]

На этом всё, надеемся, предоставленная информация была полезной!

Удаление элементов в ArrayList

Как известно, после удаления элемента из середины списка ArrayList, часть массива, которая следовала после данного элемента, перезаписывается на позицию влево, чтоб перекрыть пустую ячейку. Если стоит задача удалить несколько элементов из середины списка одной операцией (т. е. чтоб избежать многоразовой перезаписи массива), как это можно сделать?

Отслеживать
11 1 1 золотой знак 2 2 серебряных знака 8 8 бронзовых знаков
задан 19 дек 2014 в 13:50
romashechka romashechka
359 1 1 золотой знак 5 5 серебряных знаков 18 18 бронзовых знаков

4 ответа 4

Сортировка: Сброс на вариант по умолчанию

Как обычно - наследованием:

public class MyArrayList extends ArrayList  < public void remove(int startIndex, int endIndex) < //здесь и придумывайте свой гениальный код >> 

Отслеживать
ответ дан 19 дек 2014 в 14:00
81.3k 7 7 золотых знаков 73 73 серебряных знака 153 153 бронзовых знака
собственно вопрос и заключался в том, что там за алгоритм должен быть ))
19 дек 2014 в 14:04

Используйте методы removeAll и sublist . sublist - для создания коллекции (пула элементов), которую нужно удалить. А removeAll уже для удаления элементов.

public static void main(String[] args) < Listlist = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); list.add(6); list.add(7); list.add(8); List sublist = list.subList(2,5); // Удаляем с 2 по 4й элемент включительно list.removeAll(sublist); System.out.println(list); //[1, 2, 6, 7, 8] > > //В одну строку public static void main(String[] args) < Listlist = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); list.add(6); list.add(7); list.add(8); list.removeAll(list.subList(2,5)); System.out.println(list); //[1, 2, 6, 7, 8] > > 

Отслеживать
22k 3 3 золотых знака 27 27 серебряных знаков 37 37 бронзовых знаков
ответ дан 11 окт 2016 в 22:03
Andrii Horbatiuk Andrii Horbatiuk
51 1 1 серебряный знак 1 1 бронзовый знак

использовать removeAll(Collection c)
наследовать и использовать removeRange(int fromIndex, int toIndex)

Отслеживать
ответ дан 19 дек 2014 в 14:52
1,300 8 8 серебряных знаков 18 18 бронзовых знаков

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

Условимся, что из списка длины n нужно удалить m элементов. Формализую вопрос: m удалений, по O(n) каждое, стоит O(m×n) ; как можно ускорить процесс?

Пользуясь тем, что ArrayList#set стоит O(1) , нужно сначала отметить все элементы как удалённые:

list.set(index, REMOVED); 

где REMOVED — это приватная константа, которая в обычных условиях в списке не окаженся:

private static final Object REMOVED = new Object(); 

Дженерики будут мешать вставке произвольных Object ов, поэтому придётся воспользоваться стиранием и сделать unchecked cast.

((List) list).set(index, REMOVED); 

После этого в листе есть посторонние элементы. Осторожно: list.get(removedIndex) приведёт к ClassCastException , подробнее — см. heap pollution.

Теперь нужно удалить все элементы, которые отмечены для удаления. Вызов list.remove(REMOVED) удалит только первое вхождение; нам нужен метод removeAll , который удалит все элементы переданной коллекции из данного списка:

list.removeAll(COLLECTION_OF_REMOVED); 
private static final Collection COLLECTION_OF_REMOVED = Collections.singleton(REMOVED); 

Это произойдёт за O(n) , после чего объектов REMOVED в списке не будет и его снова можно будет безопасно читать.

Как удалить из arraylist java

В Java для удаления элемента из ArrayList можно использовать метод remove() . Вот несколько примеров:

Удаление по индексу:

ArrayListString> list = new ArrayList<>(); list.add("apple"); list.add("banana"); list.add("cherry"); // Удаляем элемент с индексом 1 (т.е. "banana") list.remove(1); 

Удаление по значению:

ArrayListString> list = new ArrayList<>(); list.add("apple"); list.add("banana"); list.add("cherry"); // Удаляем элемент со значением "banana" list.remove("banana"); 

Удаление всех элементов, удовлетворяющих условию:

ArrayListInteger> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(2); list.add(4); // Удаляем все элементы со значением 2 list.removeIf(n -> n == 2); 

В этом примере мы используем метод removeIf() , который удаляет все элементы, удовлетворяющие заданному условию. В данном случае мы передаем лямбда-выражение n -> n == 2 , которое проверяет, равен ли элемент n значению 2.

Добавить комментарий

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