Heim > Java > javaLernprogramm > 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

高洛峰
Freigeben: 2017-01-22 16:25:46
Original
1893 Leute haben es durchsucht

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());
   
 }
Nach dem Login kopieren

Ausgabeergebnis:

1
2
3
4
list=[1, 2, 3, 4]
Nach dem Login kopieren

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());
   
 }
Nach dem Login kopieren


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)
Nach dem Login kopieren

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());
 }
Nach dem Login kopieren

🎜>

2. Elemente während der Kartendurchquerung löschen

Beispiel für die richtige Vorgehensweise:

1
2
2
3
4
list=[1, 3, 4]
Nach dem Login kopieren

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());
 }
}
Nach dem Login kopieren


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
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage