Heim  >  Artikel  >  Java  >  So löschen Sie Elemente während der Listen- oder Kartendurchquerung in Java

So löschen Sie Elemente während der Listen- oder Kartendurchquerung in Java

高洛峰
高洛峰Original
2017-01-22 16:25:461824Durchsuche

Es gibt viele Möglichkeiten, Elemente in einer Liste oder Karte zu durchlaufen und zu löschen, und bei unsachgemäßer Verwendung treten Probleme auf. Lassen Sie uns in diesem Artikel mehr erfahren.

1. Elemente während des Listendurchlaufs löschen

Index-Indexdurchlauf verwenden

Beispiel: Löschen Sie 2 in der Liste

public static void main(String[] args) {
  List<Integer> list = new ArrayList<Integer>();
  list.add(1);
  list.add(2);
  list.add(2);
  list.add(3);
  list.add(4);
   
  for (int i = 0; i < list.size(); i++) {
   if(2 == list.get(i)){
    list.remove(i);
   }
   System.out.println(list.get(i));
  }
   
  System.out.println("list=" + list.toString());
   
 }

Ausgabeergebnis:

1
2
3
4
list=[1, 2, 3, 4]

Problem:

Das Ergebnis zeigt, dass nur eine 2 gelöscht wurde und die anderen 2 weggelassen wurden, warum Ja: Nach dem Löschen der ersten 2 wird die Anzahl der Elemente im Satz um 1 reduziert und die nachfolgenden Elemente werden um 1 nach vorne verschoben, wodurch die zweiten 2 weggelassen werden.

Für Schleifendurchquerung

Beispiel:

public static void listIterator2(){
  List<Integer> list = new ArrayList<Integer>();
  list.add(1);
  list.add(2);
  list.add(2);
  list.add(3);
  list.add(4);
   
  for (int value : list) {
   if(2 == value){
    list.remove(value);
   }
   System.out.println(value);
  }
   
  System.out.println("list=" + list.toString());
   
 }


Ergebnis:

Exception in thread "main" 1
2
java.util.ConcurrentModificationException
 at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
 at java.util.ArrayList$Itr.next(Unknown Source)
 at test.ListIterator.listIterator2(ListIterator.java:39)
 at test.ListIterator.main(ListIterator.java:10)

Erklärung:

Beschreibung von ConcurrentModificationException in JDK:

öffentliche Klasse ConcurrentModificationException erweitert

RuntimeException Diese Ausnahme wird ausgelöst, wenn die Methode eine gleichzeitige Änderung des Objekts erkennt, eine solche Änderung jedoch nicht zulässt.

Wenn beispielsweise ein Thread eine Sammlung durchläuft, ist es einem anderen Thread normalerweise nicht gestattet, die Sammlung linear zu ändern. In diesen Fällen sind die Ergebnisse der Iteration häufig unbestimmt. Einige Iteratorimplementierungen (einschließlich aller von der JRE bereitgestellten generischen Sammlungsimplementierungen) lösen diese Ausnahme möglicherweise aus, wenn dieses Verhalten erkannt wird. Iteratoren, die diesen Vorgang ausführen, werden als Fail-Fast-Iteratoren bezeichnet, da der Iterator völlig schnell ausfällt, ohne dass das Risiko eines willkürlichen, nicht spezifizierten Verhaltens zu einem späteren Zeitpunkt besteht.

Hinweis: Diese Ausnahme zeigt nicht immer an, dass das Objekt gleichzeitig von verschiedenen Threads geändert wurde. Ein Objekt kann diese Ausnahme auslösen, wenn ein einzelner Thread eine Folge von Methodenaufrufen ausgibt, die gegen den Vertrag des Objekts verstoßen. Wenn beispielsweise ein Thread eine Sammlung direkt ändert, während er mit einem Fail-Fast-Iterator darüber iteriert, löst der Iterator diese Ausnahme aus.

Hinweis: Das Fail-Fast-Verhalten von Iteratoren kann nicht garantiert werden, da es im Allgemeinen nicht möglich ist, feste Garantien dafür zu geben, ob unsynchronisierte gleichzeitige Änderungen auftreten. Fail-Fast-Vorgänge lösen auf Best-Effort-Basis eine ConcurrentModificationException aus. Daher ist es ein Fehler, ein Programm zu schreiben, das auf dieser Ausnahme basiert, um die Korrektheit solcher Vorgänge zu verbessern. Der richtige Ansatz ist: ConcurrentModificationException sollte nur zum Erkennen von Fehlern verwendet werden.

Für jeden in Java wird tatsächlich ein Iterator zur Verarbeitung verwendet. Der Iterator lässt nicht zu, dass die Sammlung während der Verwendung des Iterators gelöscht wird. Dies führte dazu, dass der Iterator eine ConcurrentModificationException auslöste.

Richtiger Weg

Beispiel:

public static void listIterator3(){
  List<Integer> list = new ArrayList<Integer>();
  list.add(1);
  list.add(2);
  list.add(2);
  list.add(3);
  list.add(4);
   
  Iterator<Integer> it = list.iterator();
  while (it.hasNext()){
   Integer value = it.next();
   if (2 == value) {
    it.remove();
   }
    
   System.out.println(value);
  }
   
  System.out.println("list=" + list.toString());
 }

🎜>

2. Elemente während der Kartendurchquerung löschen

Beispiel für die richtige Vorgehensweise:

1
2
2
3
4
list=[1, 3, 4]

Ergebnis:

public static void main(String[] args) {
 HashMap<String, String> map = new HashMap<String, String>();
 map.put("1", "test1");
 map.put("2", "test2");
 map.put("3", "test3");
 map.put("4", "test4");
  
 //完整遍历Map
 for (Entry<String, String> entry : map.entrySet()) {
  System.out.printf("key: %s value:%s\r\n", entry.getKey(), entry.getValue());
 }
  
 //删除元素
 Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
 while(it.hasNext())
 {
  Map.Entry<String, String> entry= it.next();
  String key= entry.getKey();
  int k = Integer.parseInt(key);
  if(k%2==1)
  {
   System.out.printf("delete key:%s value:%s\r\n", key, entry.getValue());
   it.remove();
  }
 }
  
 //完整遍历Map
 for (Entry<String, String> entry : map.entrySet()) {
  System.out.printf("key: %s value:%s\r\n", entry.getKey(), entry.getValue());
 }
}


Hinweis

Aber für die Bei der Methode „remove()“ des Iterators müssen wir auch auf folgende Dinge achten:

Jedes Mal, wenn iterator.next aufgerufen wird ()-Methode, kann die Methode „remove()“ nur einmal aufgerufen werden.
key: 1 value:test1
key: 2 value:test2
key: 3 value:test3
key: 4 value:test4
delete key:1 value:test1
delete key:3 value:test3
key: 2 value:test2
key: 4 value:test4

Vor dem Aufruf der Methode „remove()“ muss die Methode „next()“ einmal aufgerufen werden.

Beschreibung der Methode „remove()“ in der JDK-API:


void remove() entfernt das letzte vom Iterator zurückgegebene Element aus der Sammlung, auf die der Iterator zeigt (optionale Aktion). Diese Methode kann nur einmal pro Aufruf von next aufgerufen werden. Das Verhalten eines Iterators ist undefiniert, wenn die Sammlung, auf die der Iterator zeigt, während der Iteration auf andere Weise als durch den Aufruf dieser Methode geändert wird.


Wirft aus: UnsupportedOperationException – wenn der Iterator den Entfernungsvorgang nicht unterstützt. IllegalStateException – wenn die nächste Methode nicht aufgerufen wurde oder die Remove-Methode seit dem letzten Aufruf der nächsten Methode aufgerufen wurde.

Zusammenfassung

Oben geht es um das Löschen von Elementen während des Durchlaufprozesses von Liste und Karte. Ich hoffe, dass der Inhalt dieses Artikels jedem beim Lernen oder bei der Arbeit helfen kann Fragen Sie können Nachrichten hinterlassen, um zu kommunizieren.


Weitere Artikel zum Löschen von Elementen während der Listen- oder Kartendurchquerung in Java finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn