istnieją dwa sposoby usuwania obiektów z ArrayList w Javie, po pierwsze za pomocą metody remove (), a po drugie za pomocą iteratora. ArrayList udostępnia przeciążoną metodę remove (), jedną accept index obiektu, który ma zostać usunięty, tzn. remove(int index), a drugą accept obiekt, który ma zostać usunięty, tzn. remove(Object obj). Zasada jest taka, że jeśli znasz indeks obiektu, użyj pierwszej metody, w przeciwnym razie użyj drugiej metody. Przy okazji, musisz pamiętać, aby używać metod usuwania ArrayList, tylko wtedy, gdy nie iterujesz nad ArrayList jeśli iterujesz, użyj iteratora.metoda remove (), której niewykonanie może spowodować wystąpienie ConcurrentModificationException w Javie. Kolejna wpadka mogła nastąpić z powodu autoboxingu. Jeśli przyjrzysz się dokładnie, że dwie metody usuwania, remove (int index) I remove (Object obj) są nie do odróżnienia, jeśli próbujesz usunąć z ArrayList liczby całkowite.
Załóżmy, że masz trzy obiekty w ArrayList, czyli chcesz usunąć drugi obiekt, czyli 2. Możesz wywołać remove(2), które w rzeczywistości jest wywołaniem remove(Object), jeśli rozważysz autoboxing, ale będzie interpretowane jako wywołanie remove(index).
omówiłem ten problem wcześniej w moim artykule o najlepszych praktykach do naśladowania podczas przeciążania metod w Javie. Ze względu na mniej znaną regułę rozszerzania i autoboxing, słabo przeciążona metoda może stworzyć wiele niejasności.
przykład kodu aby usunąć elementy z ArrayList
przetestujmy powyższą teorię prostym przykładem kodu ArrayList z liczbami całkowitymi. Poniższy program posiada ArrayList liczb całkowitych zawierających 1, 2 i 3 tzn. odpowiada to dokładnie indeksowi.
test pakietu;import java.util.ArrayList; import java.util.List;/** * * @author http://java67.blogspot.com */public class JavaTutorial{ /** * @param args argumenty wiersza poleceń */ public static void main(String args) { List<Integer> numbers = new ArrayList<integer>(); liczby.add (1); Liczby.add (2); liczby.add (3); System.Wynocha.println ("ArrayList contains:" + numbers); / / wywołanie remove (index) numbers.remove(1); //usunięcie obiektu o indeksie 1, tzn. drugiego obiektu, czyli 2 //wywołanie numerów remove(object).remove(3); }}Output:ArrayList zawiera : wyjątek w wątku "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 2 w Javie.util.ArrayList.rangeCheck (ArrayList.java: 635) w języku java.util.ArrayList.usunąć (ArrayList.java: 474) W teście.Test.główna (Test.java:33)Java Result: 1
widać, że drugie wywołanie jest również traktowane jako remove(index). Najlepszym sposobem na usunięcie niejednoznaczności jest usunięcie autoboxingu i dostarczenie rzeczywistego obiektu, jak pokazano poniżej.
System.Wynocha.println ("ArrayList Before:" + numbers); / / wywołanie remove (index)numbers.remove(1); //usunięcie obiektu o indeksie 1, tzn. drugiego obiektu, czyli 2 //wywołanie numerów remove(object).remove(new Integer (3));System.Wynocha.println ("ArrayList After:" + numbers); Output: ArrayList Before: ArrayList After:
tym razem działa, ale boję się leniwych programistów takich jak ja, co wymaga autoboxingu. Teraz rzućmy okiem na usunięcie obiektu z ArrayList podczas iteracji nad nimi. Musisz znać Iterator w Javie, zanim przejdziesz dalej.
Usuń obiekt z ArrayList za pomocą iteratora
jest to w rzeczywistości subtelny szczegół programowania Javy, nieoczywisty dla początkujących, ponieważ kompilator nie będzie narzekał, nawet jeśli użyjesz metody remove() z Javy.util.ArrayList, podczas korzystania z iteratora. Zdasz sobie sprawę ze swojego błędu tylko wtedy, gdy zobaczysz ConcurrentModificationException, który sam w sobie jest mylący i możesz spędzić niezliczone godziny na znalezieniu innego wątku, który modyfikuje tę ArrayList, z powodu współbieżnego słowa. Zobaczmy przykład.
public static void main(String args) { List<Integer> numbers = new ArrayList<Integer>(); numery.Dodaj (101); liczby.add (200); liczby.dodaj (301); liczby.system add (400);.Wynocha.println ("ArrayList Before:" + numbers); Iterator<Integer> itr = numbers.iterator(); // remove all even numbers while (itr.hasNext()) { Integer number = itr.next(); if (number % 2 == 0) { numbers.remove(number); } } System.out.println("ArrayList After : " + numbers); }Output :ArrayList Before : Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859) at java.util.ArrayList$Itr.next(ArrayList.java:831) at Testing.main(Testing.java:28)
możesz współbieżnie Modificationexception, z powodu wywołania metody remove() Z ArrayList. Jest to łatwe w prostych przykładach, ale w prawdziwym projekcie może być naprawdę trudne. Teraz, aby naprawić ten wyjątek, po prostu zastąp wywołanie liczb.usuń () do itr.remove(), spowoduje usunięcie bieżącego obiektu, który Iterujesz, jak pokazano poniżej:
System.Wynocha.println ("ArrayList Before:" + numbers);Iterator<Integer> itr = numbers.iterator (); / / usuń wszystkie liczby parzyste (itr.hasNext()) { liczba całkowita = itr.next(); if (Liczba % 2 == 0) { itr.remove ();}} System.Wynocha.println ("ArrayList After:" + numbers);OutputArrayList Before: ArrayList After:
to wszystko w tym poście o tym, jak usunąć obiekt z ArrayList w Javie. Nauczyliśmy się dwóch sposobów usuwania obiektu lub elementu z ArrayList. Przy okazji, zawsze powinieneś używać remove (index), aby usunąć obiekt, jeśli nie iteratujesz, w przeciwnym razie zawsze używaj metody remove () iteratora do usuwania obiektu z ArrayList. Przy okazji powyższe wskazówki będą działać z dowolną implementacją listy opartej na indeksie.
dalsza nauka
Java In-Depth: Zostań inżynierem Javy
Java Fundamentals: Collections
struktury danych i algorytmy: Głębokie nurkowanie przy użyciu Javy
algorytmy i struktury danych-Część 1 i 2
struktury danych w Javie 9 Heinz Kabutz