Saat belajar koleksi di Java, dicatat bahwa koleksi koleksi koleksi koleksi antarmuka hirarki mengimplementasikan antarmuka <T> iterable (terletak di paket java.lang), yang memungkinkan objek menjadi target pernyataan "foreach". Satu-satunya cara dalam antarmuka ini adalah mengembalikan iterator yang berulang pada satu set elemen tipe-t.
1. Iterator
Antarmuka: Iterator <T>
Iterator Antarmuka Publik <E> {boolean hasnext (); E next (); void remain (); }Melihat API antarmuka Iterator, Anda dapat tahu bahwa ini adalah iterator yang berulang kali di atas koleksi. Iterator memungkinkan penelepon untuk menghapus elemen dari koleksi yang ditunjukkan oleh iterator selama iterasi menggunakan semantik yang terdefinisi dengan baik.
Perlu dicatat bahwa metode ini menghapus () metode ini digunakan: lepaskan elemen terakhir yang dikembalikan oleh iterator dari koleksi yang ditunjukkan oleh iterator (operasi opsional). Metode ini hanya dapat dipanggil sekali per panggilan berikutnya. Jika koleksi yang ditunjuk oleh iterator dimodifikasi dengan cara lain selain memanggil metode ini (menghapus metode) saat berulang, perilaku iterator tidak pasti. Saat merancang antarmuka Iterator <T>, perancang antarmuka telah menunjukkan bahwa ketika iterasi, jika metode lepas () kecuali iterator dipanggil dan pengumpulan yang ditunjukkan oleh iterator dimodifikasi, itu akan menyebabkan konsekuensi yang tidak pasti. Apa konsekuensinya tergantung pada implementasi spesifik iterator. Menanggapi situasi yang mungkin dari konsekuensi yang tidak pasti ini, salah satunya ditemui ketika mempelajari Daftar Array: Iterator melempar pengecualian Exception ConcurrentModification. Pengecualian spesifik ditampilkan dalam kode berikut:
Impor java.util.arraylist; import java.util.collection; import java.util.iterator; kelas publik itaratortest {public static void main (string [] args) {collection <string> list = new ArrayList <string> (); list.add ("android"); list.add ("ios"); list.add ("Windows Mobile"); Iterator <string> iterator = list.iterator (); while (iterator.hasnext ()) {string lang = iterator.next (); list.remove (lang); // akan melempar concurrentmodificationException}}} Kode ini akan melempar pengecualian ConcurrentModificationException saat berjalan, karena kami tidak menggunakan metode hapus () iterator untuk menghapus elemen selama run iterator, tetapi menggunakan metode lepas () arraylist untuk mengubah koleksi yang ditunjukkan oleh iterator. Ini melanggar prinsip -prinsip desain iterator, jadi pengecualian terjadi.
Kelainan yang dilaporkan adalah sebagai berikut:
Pengecualian di utas "utama" java.util.concurrentModificationException
di java.util.arraylist $ ittr.CheckForComodification (arraylist.java:859)
di java.util.arraylist $ ittr.next (arraylist.java:831)
di Text.itarTortest.main (itaratortest.java:17)
2. UNTUK MENGHIDUPKAN LOOP DAN ITERATOR ITERATOR <T>
Mulai dari Java 5, ada loop untuk setiap di Java, yang dapat digunakan untuk mengulangi koleksi dan array. Foreach Loop memungkinkan Anda untuk melintasi koleksi tanpa memanggil metode hasnext () dalam loop sementara tanpa menjaga indeks dalam loop tradisional, atau menggunakan iterator /listiterator (implementasi iterator di arraylist). Loop untuk mendapatkan proses traversal dari koleksi atau array apa pun. Namun, ada dua poin yang harus diperhatikan saat menggunakan loop foreach.
Objek yang menggunakan loop foreach harus mengimplementasikan antarmuka <T> iterable
Silakan lihat contoh berikut:
Impor java.util.arraylist; kelas publik foreachtest1 {public static void main (string args []) {customCollection <string> myCollection = customCollection baru <string> (); mycollection.add ("java"); MyCollection.add ("Scala"); mycollection.add ("groovy"); // Apa yang akan dilakukan kode ini, cetak bahasa, lempar pengecualian atau // kesalahan waktu kompilasi untuk (bahasa string: myCollection) {system.out.println (bahasa); }} kelas privat CustomCollection <t> {private arrayList <T> bucket; Public CustomCollection () {bucket = new arraylist (); } public int size () {return bucket.size (); } public boolean isEmpty () {return bucket.isempty (); } public boolean berisi (t o) {return bucket.contains (o); } public boolean add (t e) {return bucket.add (e); } public boolean hapus (t o) {return bucket.remove (o); }}} Kode di atas tidak akan dikompilasi, karena kelas CustomCollection dalam kode tidak mengimplementasikan antarmuka <T> iterable, dan kesalahan yang dilaporkan selama periode kompilasi adalah sebagai berikut:
Pengecualian di Thread "Main" Java.lang.Error: Masalah kompilasi yang belum terselesaikan:
Hanya dapat mengulangi array atau instance dari java.lang
di Text.FOREACHTEST1.MAIN (FOREACHTEST1.JAVA:15)
Bahkan, tidak perlu menunggu sampai kompilasi untuk menemukan kesalahan. Eclipse akan menampilkan kesalahan dalam loop foreach setelah kode selesai: hanya dapat mengulangi di atas array atau instance dari java.lang.
Dapat dikonfirmasi lagi dari contoh di atas bahwa loop foreach hanya berlaku untuk objek yang mengimplementasikan antarmuka <T> iterable. Karena semua kelas koleksi bawaan mengimplementasikan antarmuka java.util.collection dan telah mewarisi iterable, untuk menyelesaikan masalah di atas, Anda dapat memilih untuk mengaktifkan CustomCollection untuk mengimplementasikan antarmuka koleksi atau mewarisi pengumpulan abstrak. Solusinya adalah sebagai berikut:
impor java.util.abstractcollection; import java.util.arraylist; import java.util.iterator; kelas publik foreachtest {public static void main (string args []) {customCollection <string> mycollection = customCollection baru <string> (); mycollection.add ("java"); MyCollection.add ("Scala"); mycollection.add ("groovy"); untuk (bahasa string: myCollection) {System.out.println (bahasa); }} private static class CustomCollection <T> memperluas abstrakcollection <t> {private arrayList <T> bucket; Public CustomCollection () {bucket = new arraylist (); } public int size () {return bucket.size (); } public boolean isEmpty () {return bucket.isempty (); } public boolean berisi (objek o) {return bucket.contains (o); } public boolean add (t e) {return bucket.add (e); } public boolean hapus (objek o) {return bucket.remove (o); } @Override Public Iterator <T> iterator () {// TODO METODE AUTO-DEPAN PUTP BUCKET.ITERATOR (); }}}2. Implementasi internal loop foreach juga diimplementasikan oleh Iterator.
Untuk memverifikasi fakta bahwa loop foreach menggunakan Iterator sebagai implementasi internal, kami masih menggunakan contoh awal artikel ini untuk memverifikasi:
Public Class ItAraTortest {public static void main (string [] args) {collection <string> list = new ArrayList <String> (); list.add ("android"); list.add ("ios"); list.add ("Windows Mobile"); // example1 // iterator <string> iterator = list.iterator (); // while (iterator.hasnext ()) {// string lang = iterator.next (); // list.remove (lang); //} // Contoh 2 untuk (string bahasa: daftar) {list.remove (bahasa); }}} Pengecualian dilaporkan saat program berjalan:
Pengecualian di utas "utama" java.util.concurrentModificationException
di java.util.arraylist $ ittr.CheckForComodification (arraylist.java:859)
di java.util.arraylist $ ittr.next (arraylist.java:831)
di Text.itarTortest.main (itaratortest.java:22)
Pengecualian ini hanya menunjukkan bahwa loop for-each menggunakan iterator untuk mengulangi melalui koleksi, yang juga menyebut iterator.next (), yang memeriksa perubahan (elemen) dan melempar concurrentModificationException.
Meringkaskan:
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.