เมื่อเรียนรู้คอลเลกชันใน Java จะมีการบันทึกไว้ว่าคอลเลกชันอินเทอร์เฟซรูทลำดับชั้นของคอลเลกชันจะใช้อินเตอร์เฟส iterable <t> (อยู่ในแพ็คเกจ java.lang) ซึ่งช่วยให้วัตถุกลายเป็นเป้าหมายของคำสั่ง "foreach" วิธีเดียวในอินเทอร์เฟซนี้คือการส่งคืนตัววนซ้ำที่วนซ้ำในชุดขององค์ประกอบ T-type
1. iterator
อินเตอร์เฟส: ตัววนซ้ำ <t>
Iterator อินเตอร์เฟสสาธารณะ <E> {Boolean Hasnext (); e next (); โมฆะลบ (); -เมื่อดูที่ Iterator Interface API คุณสามารถรู้ได้ว่านี่เป็นตัววนซ้ำที่วนซ้ำผ่านคอลเลกชัน ตัววนซ้ำอนุญาตให้ผู้โทรลบองค์ประกอบออกจากคอลเลคชั่นที่ชี้ไปที่ตัววนซ้ำในระหว่างการทำซ้ำโดยใช้ความหมายที่กำหนดไว้อย่างดี
เป็นเรื่องสำคัญอย่างยิ่งที่ใช้วิธีการวนซ้ำ () นี้: ลบองค์ประกอบสุดท้ายที่ส่งคืนโดยตัววนซ้ำออกจากคอลเลคชั่นที่ชี้ไปที่ตัววนซ้ำ (การดำเนินการเสริม) วิธีนี้สามารถเรียกได้เพียงครั้งเดียวต่อการโทรถัดไป หากคอลเลกชันชี้ไปที่ตัววนซ้ำได้รับการแก้ไขด้วยวิธีอื่นนอกเหนือจากการเรียกใช้วิธีนี้ (ลบเมธอด) เมื่อวนซ้ำพฤติกรรมของตัววนซ้ำจะไม่แน่นอน เมื่อออกแบบอินเทอร์เฟซ Iterator <T> ตัวออกแบบอินเตอร์เฟสได้ชี้ให้เห็นว่าเมื่อวนซ้ำหากวิธีการลบ () ยกเว้นตัววนซ้ำจะถูกเรียกและคอลเลคชั่นที่ชี้ไปที่ตัววนซ้ำจะถูกแก้ไขมันจะทำให้เกิดผลที่ไม่แน่นอน ผลที่ตามมาคืออะไรขึ้นอยู่กับการใช้งานเฉพาะของตัววนซ้ำ ในการตอบสนองต่อสถานการณ์ที่เป็นไปได้ของผลที่ไม่แน่นอนนี้หนึ่งในนั้นพบเมื่อเรียนรู้ arraylist: ตัววนซ้ำโยนข้อยกเว้น Exception พร้อมกัน ข้อยกเว้นเฉพาะจะแสดงในรหัสต่อไปนี้:
นำเข้า java.util.arraylist; นำเข้า java.util.collection; นำเข้า java.util.iterator; คลาสสาธารณะ itaratortest {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {คอลเลกชัน <string> รายการ = arraylist ใหม่ <string> (); list.add ("Android"); list.add ("iOS"); list.add ("Windows Mobile"); Iterator <String> iterator = list.iterator (); ในขณะที่ (iterator.hasnext ()) {string lang = iterator.next (); list.remove (lang); // จะโยน ConcurrentModificationException}}}} รหัสนี้จะส่งข้อยกเว้น Excession Exception พร้อมกันเมื่อทำงานเนื่องจากเราไม่ได้ใช้วิธีการลบ () ของตัววนซ้ำเพื่อลบองค์ประกอบในระหว่างการทำงานของตัววนซ้ำ แต่ใช้วิธีการลบ () ของ arrayList เพื่อเปลี่ยนคอลเลกชันที่ชี้ไปที่ตัววนซ้ำ สิ่งนี้ละเมิดหลักการออกแบบของตัววนซ้ำดังนั้นจึงมีข้อยกเว้นเกิดขึ้น
ความผิดปกติที่รายงานมีดังนี้:
ข้อยกเว้นในเธรด "หลัก" java.util.concurrentModificationException
ที่ java.util.arraylist $ ittr.checkforcomodification (arraylist.java:859)
ที่ java.util.arraylist $ ittr.next (arraylist.java:831)
ที่ text.itaratortest.main (itaratortest.java:17)
2. สำหรับการวนรอบและตัววนซ้ำ iterator <t>
เริ่มต้นจาก Java 5 มีการวนรอบสำหรับการแข่งขันใน Java ซึ่งสามารถใช้ในการวนซ้ำผ่านคอลเลกชันและอาร์เรย์ Foreach Loops ช่วยให้คุณสามารถสำรวจคอลเลกชันโดยไม่ต้องเรียกวิธี Hasnext () ในขณะที่ลูปโดยไม่เก็บดัชนีไว้ในแบบดั้งเดิมสำหรับลูปหรือใช้ตัววนซ้ำ /listiterator (การติดตั้งตัววนซ้ำใน ArrayList) การวนรอบสำหรับการแล่นอย่างง่ายดายทำให้กระบวนการข้ามของคอลเลกชันหรืออาร์เรย์ง่ายขึ้น อย่างไรก็ตามมีสองคะแนนที่จะให้ความสนใจเมื่อใช้ foreach loops
วัตถุที่ใช้ foreach loops จะต้องใช้อินเตอร์เฟส iterable <t>
โปรดดูตัวอย่างต่อไปนี้:
นำเข้า java.util.arraylist; คลาสสาธารณะ foreachtest1 {โมฆะคงที่สาธารณะหลัก (สตริง args []) {customCollection <String> myCollection = ใหม่ customCollection <String> (); mycollection.add ("java"); mycollection.add ("scala"); mycollection.add ("groovy"); // รหัสนี้จะทำอย่างไรพิมพ์ภาษาข้อยกเว้นหรือ // รวบรวมข้อผิดพลาดเวลาสำหรับ (ภาษาสตริง: MyCollection) {System.out.println (ภาษา); }} คลาสส่วนตัว CustomCollection <T> {Private ArrayList <T> Bucket; Public CustomCollection () {bucket = new ArrayList (); } ขนาด int สาธารณะ () {return bucket.size (); } บูลีนสาธารณะ isempty () {return bucket.isempty (); } บูลีนสาธารณะประกอบด้วย (t o) {return bucket.contains (o); } บูลีนสาธารณะเพิ่ม (t e) {return bucket.add (e); } บูลีนสาธารณะลบ (t o) {return bucket.remove (o); - รหัสข้างต้นจะไม่ถูกรวบรวมเนื่องจากคลาส CustomCollection ในรหัสไม่ได้ใช้อินเตอร์เฟส <T> ที่วนซ้ำและข้อผิดพลาดที่รายงานในระหว่างระยะเวลาการรวบรวมมีดังนี้:
ข้อยกเว้นในเธรด "Main" java.lang.error: ปัญหาการรวบรวมที่ไม่ได้รับการแก้ไข:
สามารถทำซ้ำได้มากกว่าอาร์เรย์หรืออินสแตนซ์ของ java.lang.iterable
ที่ text.foreachtest1.main (foreachtest1.java:15)
ในความเป็นจริงไม่จำเป็นต้องรอจนกว่าการรวบรวมเพื่อค้นหาข้อผิดพลาด Eclipse จะแสดงข้อผิดพลาดในลูป foreach หลังจากรหัสเสร็จแล้ว: สามารถทำซ้ำได้มากกว่าอาร์เรย์หรืออินสแตนซ์ของ java.lang.iterable
สามารถยืนยันได้อีกครั้งจากตัวอย่างข้างต้นว่า foreach loop นั้นใช้ได้เฉพาะกับวัตถุที่ใช้อินเตอร์เฟส iterable <t> เนื่องจากคลาสคอลเลกชันในตัวทั้งหมดใช้อินเทอร์เฟซ Java.util.Collection และได้รับการแก้ไขซ้ำเพื่อแก้ปัญหาข้างต้นคุณสามารถเลือกที่จะเปิดใช้งาน CustomCollection เพื่อใช้งานอินเตอร์เฟสคอลเลกชันหรือสืบทอดบทคัดย่อ การแก้ปัญหามีดังนี้:
นำเข้า java.util.abstractCollection; นำเข้า java.util.arrayList; นำเข้า java.util.iterator; ชั้นเรียนสาธารณะ foreachtest {โมฆะคงที่สาธารณะหลัก mycollection.add ("java"); mycollection.add ("scala"); mycollection.add ("groovy"); สำหรับ (ภาษาสตริง: myCollection) {system.out.println (ภาษา); }} customcollection คลาสคงที่ส่วนตัว <T> ขยายบทคัดย่อ abstractCollection <t> {private arraylist <t> bucket; Public CustomCollection () {bucket = new ArrayList (); } ขนาด int สาธารณะ () {return bucket.size (); } บูลีนสาธารณะ isempty () {return bucket.isempty (); } บูลีนสาธารณะประกอบด้วย (Object O) {return bucket.contains (O); } บูลีนสาธารณะเพิ่ม (t e) {return bucket.add (e); } บูลีนสาธารณะลบ (วัตถุ o) {return bucket.remove (o); } @Override Public Iterator <t> iterator () {// วิธีการที่สร้างขึ้นอัตโนมัติวิธีการส่งคืน bucket.iterator (); -2. การใช้งานภายในของลูป foreach ยังถูกนำมาใช้โดยตัววนซ้ำ
ในการตรวจสอบความจริงที่ว่า Foreach Loop ใช้ตัววนซ้ำเป็นการใช้งานภายในเรายังคงใช้ตัวอย่างเริ่มต้นของบทความนี้เพื่อตรวจสอบ:
คลาสสาธารณะ itaratortest {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {คอลเลกชัน <string> list = new ArrayList <String> (); list.add ("Android"); list.add ("iOS"); list.add ("Windows Mobile"); // example1 // iterator <string> iterator = list.iterator (); // ในขณะที่ (iterator.hasnext ()) {// string lang = iterator.next (); // list.remove (lang); //} // ตัวอย่าง 2 สำหรับ (ภาษาสตริง: รายการ) {list.remove (ภาษา); - รายงานข้อยกเว้นเมื่อโปรแกรมทำงาน:
ข้อยกเว้นในเธรด "หลัก" java.util.concurrentModificationException
ที่ java.util.arraylist $ ittr.checkforcomodification (arraylist.java:859)
ที่ java.util.arraylist $ ittr.next (arraylist.java:831)
ที่ text.itaratortest.main (itaratortest.java:22)
ข้อยกเว้นนี้เพียงแสดงให้เห็นว่าการวนรอบสำหรับ iterator เพื่อวนซ้ำผ่านคอลเลกชันซึ่งเรียกว่า iterator.next () ซึ่งตรวจสอบการเปลี่ยนแปลง (องค์ประกอบ) และโยนการทำพร้อมกัน Exception
สรุป:
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น