Ada banyak cara untuk melintasi dan menghapus elemen dalam daftar atau peta, dan masalah akan muncul ketika digunakan secara tidak benar. Mari kita pelajari dari artikel ini di bawah ini.
1. Hapus elemen selama traversal daftar
Gunakan traversal subskrip indeks
Contoh: Hapus 2 dalam daftar
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); untuk (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 ()); }Hasil output:
1234list = [1, 2, 3, 4]
pertanyaan:
Hasilnya menunjukkan bahwa hanya satu 2 yang dihapus, dan 2 lainnya terlewatkan. Alasannya adalah: setelah menghapus 2 pertama, jumlah elemen dalam set dikurangi dengan 1, dan elemen -elemen selanjutnya dipindahkan ke depan dengan 1 bit, menghasilkan 2 yang kedua terlewatkan.
Cara menggunakan untuk loop traversal
Contoh:
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); untuk (value int: list) {if (2 == value) {list.remove (value); } System.out.println (nilai); } System.out.println (nilai); } System.out.println ("list =" + list.toString ()); }hasil:
Pengecualian di Thread "Main" 12java.util.concurrentModificationException di java.util.arraylist $ ittr.CheckForComodification (sumber yang tidak diketahui) di java.util.arraylist $ ittr.next (tidak diketahui sumber) di test.listiterator.listiterator (listerator.jav (tidak diketahui) di test.listiterator.listiterator (listerator.jav (tidak diketahui) di test.listiterator.listiterator (listiterator.jav (tidak diketahui) di test.listiterator.listiterator (listiterator.jav) di test.listiterator.listiterator (listerator. test.listiterator.main (listiterator.java:10)
menjelaskan:
Deskripsi ConcurrentModificationException di JDK:
public class ConcurrentModificationException extends
RuntimeException Pengecualian ini dilemparkan ketika metode mendeteksi modifikasi bersamaan dari objek tetapi tidak mengizinkan modifikasi tersebut.
Misalnya, ketika utas berulang pada koleksi, modifikasi linier lain biasanya tidak diizinkan untuk dibuat. Biasanya dalam kasus ini, hasil iterasi tidak pasti. Jika perilaku ini terdeteksi, beberapa implementasi iterator (termasuk semua implementasi koleksi umum yang disediakan oleh JRE) dapat memilih untuk melempar pengecualian ini. Iterator yang melakukan operasi ini disebut iterator kegagalan cepat karena iterator gagal dengan sangat cepat tanpa mempertaruhkan risiko perilaku tidak pasti sewenang -wenang di suatu waktu di masa depan.
Catatan : Pengecualian ini tidak selalu menunjukkan bahwa objek telah dimodifikasi secara bersamaan oleh utas yang berbeda. Jika satu utas mengeluarkan urutan metode panggilan yang melanggar kontrak objek, objek dapat melemparkan pengecualian ini. Misalnya, jika utas secara langsung memodifikasi koleksi saat mengulangi koleksi menggunakan iterator gagal cepat, iterator akan melempar pengecualian ini.
Catatan : Perilaku kegagalan cepat dari iterator tidak dapat dijamin, karena secara umum, tidak mungkin untuk membuat jaminan sulit tentang apakah ada modifikasi bersamaan yang tidak sinkron. Operasi kegagalan cepat akan melakukan yang terbaik untuk melempar ConcurrentModificationException . Oleh karena itu, adalah salah untuk menulis program yang tergantung pada pengecualian ini untuk meningkatkan kebenaran operasi tersebut. Cara yang benar adalah: ConcurrentModificationException harus digunakan hanya untuk mendeteksi bug.
Untuk masing -masing di Java benar -benar menggunakan Iterator untuk diproses. Iterator tidak mengizinkan koleksi dihapus selama penggunaan iterator. Ini menyebabkan iterator melempar ConcurrentModificationException .
Cara yang benar
Contoh:
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 ()) {value integer = it.next (); if (2 == value) {it.remove (); } System.out.println (nilai); } System.out.println (nilai); } System.out.println ("list =" + list.toString ()); }hasil:
12234List = [1, 3, 4]
2. Hapus elemen selama peta traversal
Contoh pendekatan yang benar:
public static void main (string [] args) {hashmap <string, string> map = new HashMap <string, string> (); peta.put ("1", "test1"); peta.put ("2", "test2"); peta.put ("3", "test3"); peta.put ("4", "test4"); // Traversal penuh dari peta untuk (entri <string, string> entri: map.entryset ()) {System.out.printf ("Kunci: %S Nilai: %s/r/n", entri.getKey (), entri.getValue ()); } // hapus elemen iterator <map.entry <string, string >> it = map.entryset (). Iterator (); while (it.hasnext ()) {map.entry <string, string> entri = it.next (); String key = entry.getKey (); int k = integer.parseint (key); if (k%2 == 1) {System.out.printf ("Hapus tombol:%S Nilai:%s/r/n", key, entri.getValue ()); it.remove (); }} // peta traverse penuh untuk (entri <string, string> entri: map.entryset ()) {System.out.printf ("Kunci: %S Nilai: %s/r/n", entri.getKey (), entri.getValue ()); }}hasil:
Kunci: 1 Nilai: Test1Key: 2 Nilai: Test2Key: 3 Nilai: Test3Key: 4 Nilai: Test4Delete Kunci: 1 Nilai: Test1Delete Kunci: 3 Nilai: Test3Key: 2 Nilai: Test2Key: 4 Nilai: Test4
Melihat
Tetapi ada juga hal -hal yang perlu kita perhatikan tentang metode remove() dari iterator:
Metode remove() iterator.next() () dipanggil.
Sebelum memanggil metode remove() , metode next() harus dipanggil sekali.
Deskripsi metode remeh () di JDK-API:
void remove() Menghapus elemen terakhir yang dikembalikan oleh iterator dari koleksi yang ditunjuk oleh iterator (operasi opsional). Metode ini hanya dapat dipanggil sekali per panggilan berikutnya. Jika iterator dimodifikasi dengan cara selain memanggil metode ini saat iterasi, perilaku iterator ambigu.
Lemparan: UnsupportedOperationException - Jika iterator tidak mendukung operasi remove . IllegalStateException - Jika metode next belum dipanggil, atau metode remove telah dipanggil setelah panggilan terakhir ke metode next .
Meringkaskan
Di atas adalah semua tentang menghapus elemen selama traversal daftar dan peta. Saya berharap konten artikel ini akan membantu untuk belajar atau bekerja semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi.