Perbezaan polimorfik (lapisan bawah foreach ialah Iterator)
:
Kod dinyahkompilasi:
2 semasa foreach dan iterator Mari kita lihat
Ali first Java Development ManualTetapi tiada ralat akan dilaporkan dalam 1, dan ralat akan dilaporkan dalam 2 (java.util.ConcurrentModificationException )
Pertama sekali Lihatlah pelaksanaan kaedah iterator dalam ArrayList:
memanggil Itr() baharu untuk menjana kelas Itr (iterator). Pada masa ini, tiga parameter Itr akan dimulakan.
kursor mewakili kedudukan indeks seterusnya (bermula pada 0)
saiz ialah saiz koleksi (2)kaedah seterusnya () akan menyemak sama ada checkForComodification adalah sama
kiraan pengubahsuaian modCount (setiap tambah dan buang akan +1) expectedModCount dijangka kiraan maksimum
1.alih keluar analisis kod sumber operasi
Pertama, mari kita lihat pada pemadaman “ 2 "Situasi:
Gelung pertama: Oleh kerana modCount dan expectedModCount pada masa ini adalah kedua-duanya 2 (modCount ialah 2 kerana ia telah ditambah dua kali), jadi ia tidak akan dilemparkan dalam gelung pertama Pengecualian dan pengecualian dilemparkan apabila ia bukan kali pertama dalam gelung. Selepas kaedah seterusnya selesai, keadaan if kaedah alih keluar dalam badan kaedah gelung foreach tidak berpuas hati, dan gelung berakhir. Gelung kedua:Kaedah hasNext dan seterusnya bagi gelung kedua boleh diselesaikan dengan jayanya Selepas itu, ia akan memasukkan kaedah keluarkan dalam badan kaedah gelung foreach. Pada masa ini, saiz-1 menjadi 1. Dalam kaedah fastRemove dalam kaedah alih keluar, modCount+1 ditambah, yang menjadi 3.
Gelung ketiga:
Kemudian ia akan pergi ke kaedah hasNext dalam gelung ketiga. Dalam keadaan biasa, kaedah ini akan mengembalikan palsu, tetapi kerana saiz pada masa ini telah berubah kepada 1, dan kursor pada masa ini ialah 2 (kursor mewakili kedudukan indeks seterusnya), jadi kedua-duanya tidak sama dan ralat dikembalikan . true, jadi ia akan terus pergi ke kaedah checkForComodification dalam kaedah seterusnya untuk menentukan sama ada modCount dan expectedModCount pada masa ini adalah sama. Oleh kerana modCount pada masa ini telah berubah kepada 3, yang berbeza daripada nilai expectedModCount 2, pengecualian ConcurrentModificationException telah dilemparkan di sini.
Mari kita lihat mengapa tiada pengecualian dilemparkan apabila memadamkan "1":
Gelung pertama:
Sama seperti di atas, modCount dan expectedModCount pada masa ini adalah kedua-duanya 2, jadi kaedah hasNext dan seterusnya dalam gelung pertama tidak akan membuang pengecualian. Selepas ini, anda akan memasukkan kaedah alih keluar dalam badan kaedah gelung foreach untuk memadamkan elemen. Sama seperti di atas, saiz-1 menjadi 1, dan modCount+1 menjadi 3.
Gelung kedua:
Dalam kaedah hasNext bagi gelung kedua, kursor pada masa ini ialah 1, dan saiznya juga 1, dan kedua-duanya adalah sama. . Oleh itu, apabila kaedah hasNext mengembalikan palsu, ia akan melompat keluar dari gelung foreach dan tidak akan pergi ke kaedah seterusnya seterusnya, jadi ia tidak akan membuang pengecualian. 2. Langkah kod sumberPertama kali
Panggil iterator() dalam ayat ①,Itr() baharu dipanggil untuk menjana kelas Itr (iterator). Pada masa ini, tiga parameter Itr akan dimulakan.
Pada masa ini expectedModCount == modCount == 2 (kerana senarai menggerakkan kaedah tambah, kaedah tambah akan melaksanakan operasi ++ pada modCount)
Dalam ayat ②, panggil kaedah hasNext() di bawah untuk kembali elemen seterusnya untuk diakses Kursor subskrip, kerana ia adalah gelung pertama, jadi kursor ialah 0 dan saiznya ialah 2 (0 != 2 benar)
Ayat ③ memanggil kaedah seterusnya() dan syarat if penghakiman kaedah alih keluar dalam badan kaedah gelung foreach Jika tidak berpuas hati, kitaran tamat
Kali kedua
Ayat kedua memanggil kaedah hasNext() di bawah untuk kembalikan kursor subskrip elemen seterusnya untuk diakses , gelung kedua, jadi kursor ialah 1,
saiz masih 2 (1 != 2 benar)
Kaedah seterusnya() dipanggil dalam ayat ③, nilai diambil secara normal, dan elemen pertama "2" diperoleh ;
Ayat 4 memanggil kaedah remove() dan berjaya memadamkan elemen daripada senarai. Ambil perhatian bahawa apabila memanggil kaedah keluarkan, terdapat modCount++. Pada masa ini, modCount3, expectedModCount2, size1
Kali ketiga
Ayat ② memanggil kaedah hasNext() berikut dan mengembalikan kursor subskrip elemen seterusnya untuk diakses. , gelung kedua, jadi kursor ialah 2 dan saiznya ialah 1
Kaedah seterusnya() dipanggil dalam ayat ke-3 Perhatikan bahawa ayat pertama dalam kaedah seterusnya() ialah memanggil checkForComodification(. ); disebabkan oleh modCount(3) = expectedModCount(2), jadi pengecualian telah dilemparkan.
Apabila gelung berakhir, manakala (iterator.hasNext() ) akan menyemak sama ada terdapat elemen seterusnya Selepas membuang delete 2 selesai, kali seterusnya anda memasukkan kursor masih 1, dan saiznya juga 1.
Foreach, selepas mengeluarkan remove2, kali seterusnya anda memasukkan kursor. ialah 2, dan saiznya ialah 1, jadi Untuk mengembalikan palsu, pergi ke kaedah seterusnya, dan kemudian semak, modCount=3, dan expectedModCount=2
Jika anda melihat ArrayList di bawah iterator
Atas ialah kandungan terperinci Apakah perbezaan antara menggunakan foreach dan iterator untuk memadam elemen semasa melintasi Java ArrayList?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!