“สวัสดี อามีโก้!”
“สวัสดี เอลลี่!”
"วันนี้ฉันอยากจะบอกคุณเกี่ยวกับ iterators"
"ตัววนซ้ำถูกประดิษฐ์ขึ้นจริงในเวลาเดียวกับคอลเลกชั่น จุดประสงค์หลักของคอลเลกชั่นคือการจัดเก็บองค์ประกอบ และจุดประสงค์หลักของตัววนซ้ำคือดึงองค์ประกอบเหล่านี้ทีละรายการ"
"อะไรเป็นเรื่องยากในการหาชุดองค์ประกอบ?"
"ประการแรก องค์ประกอบในบางคอลเลกชัน เช่น ชุด ไม่มีลำดับที่กำหนดไว้ และ/หรือลำดับเปลี่ยนแปลงตลอดเวลา"
"ประการที่สอง โครงสร้างข้อมูลบางอย่างอาจจัดเก็บวัตถุด้วยวิธีที่ซับซ้อนมาก: ในกลุ่มต่างๆ รายการ ฯลฯ กล่าวอีกนัยหนึ่ง การกระจายองค์ประกอบทั้งหมดตามลำดับจะเป็นงานที่ไม่สำคัญ"
"ประการที่สาม คอลเลกชันมีแนวโน้มที่จะเปลี่ยนแปลง สมมติว่าคุณตัดสินใจที่จะแสดงเนื้อหาทั้งหมดของคอลเลกชัน แต่ตรงกลางของเอาต์พุต JVM จะสลับไปยังเธรดอื่นที่มาแทนที่องค์ประกอบครึ่งหนึ่งของคอลเลกชัน ดังนั้นแทนที่จะเป็นเอาต์พุต คุณจะได้รับ ใครจะไปรู้ล่ะ"
"อืม..."
"แต่! สิ่งเหล่านี้เป็นปัญหาที่ตัววนซ้ำสามารถแก้ไขได้ตัววนซ้ำเป็นวัตถุพิเศษภายในคอลเลกชั่นที่ในแง่หนึ่ง สามารถเข้าถึงข้อมูลส่วนตัวทั้งหมดและรู้โครงสร้างภายในของมัน และในทางกลับกัน ใช้ส่วนต่อประสาน Iterator สาธารณะซึ่งช่วยให้ทุกคนรู้วิธีการทำงานกับมัน "
"ตัววนซ้ำบางตัวมีอาร์เรย์ภายในซึ่งองค์ประกอบทั้งหมดของคอลเลกชันจะถูกคัดลอกเมื่อสร้างตัววนซ้ำ สิ่งนี้ทำให้มั่นใจได้ว่าการเปลี่ยนแปลงใดๆ ที่ตามมากับคอลเลกชันจะไม่ส่งผลกระทบต่อจำนวนหรือลำดับขององค์ประกอบ"
"ฉันคิดว่าคุณเคยเจอสิ่งนี้เมื่อทำงานกับแต่ละอันคุณไม่สามารถวนซ้ำคอลเลกชั่นและลบองค์ประกอบออกจากมันได้ ทั้งหมดนี้เป็นเพราะวิธีการทำงานของตัววนซ้ำ"
"ในคอลเลกชันใหม่ที่เพิ่มในไลบรารีการทำงานพร้อมกัน ตัววนซ้ำจะถูกทำใหม่เพื่อขจัดปัญหานี้"
"ให้ฉันเตือนคุณว่าตัววนซ้ำทำงานอย่างไร"
"Java มีอินเทอร์เฟซ Iterator พิเศษ นี่คือวิธีการ:"
เมธอดของอินเทอร์เฟซ Iterator<E> | คำอธิบาย |
---|---|
boolean hasNext() |
ตรวจสอบว่ามีองค์ประกอบเพิ่มเติมหรือไม่ |
E next() |
ส่งกลับองค์ประกอบปัจจุบันและย้ายไปยังองค์ประกอบถัดไป |
void remove() |
ลบองค์ประกอบปัจจุบัน |
"ตัววนซ้ำช่วยให้คุณได้รับองค์ประกอบทั้งหมดของคอลเล็กชันอย่างต่อเนื่อง มีเหตุผลมากกว่าที่จะคิดว่าตัววนซ้ำเป็นเหมือน InputStream นั่นคือมีข้อมูลทั้งหมด แต่หน้าที่คือส่งออกข้อมูลตามลำดับ"
" เมธอด ถัดไป () ส่งคืนองค์ประกอบถัดไปในคอลเลกชัน"
" เมธอด hasNext () ใช้ในการตรวจสอบว่ามีองค์ประกอบเพิ่มเติมหรือไม่"
"และลบ () ลบองค์ประกอบปัจจุบัน"
"มีคำถามอะไรไหม?"
"ทำไมเมธอดถึงมีชื่อแปลกๆ ทำไมไม่เป็น isEmpty() และ getNextElement()"
“มันไม่เข้าท่ากว่าเหรอ?”
"มันสมเหตุสมผลกว่า แต่ชื่อมาจากภาษา C ++ ซึ่งตัววนซ้ำปรากฏขึ้นก่อนหน้านี้"
"เข้าใจแล้ว ไปต่อกันเถอะ"
"นอกจาก iterator แล้ว ยังมีอินเทอร์เฟซ Iterable ซึ่งต้องใช้งานโดยคอลเลกชั่นทั้งหมดที่รองรับ iterators มันมีเมธอดเดียว:"
เมธอดของอินเทอร์เฟซ Iterable<T> | คำอธิบาย |
---|---|
Iterator<T>iterator() |
ส่งกลับวัตถุตัววนซ้ำ |
"คุณสามารถใช้เมธอดนี้กับคอลเล็กชันใดก็ได้เพื่อให้ออบเจกต์ตัววนซ้ำเดินผ่านองค์ประกอบของมัน มาดูองค์ประกอบทั้งหมดใน TreeSet กัน: "
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();
while (iterator.hasNext())
{
String item = iterator.next();
System.out.println(item);
}
"การใช้ iterator แบบนี้ไม่สะดวกนัก — มีโค้ดที่ฟุ่มเฟือยและชัดเจนมากเกินไป สถานการณ์จะง่ายขึ้นเมื่อ for -eachวนซ้ำปรากฏใน Java"
"ตอนนี้รหัสนี้มีขนาดกะทัดรัดและสามารถอ่านได้มากขึ้น:"
ก่อน | หลังจาก |
---|---|
|
|
"นี่คือรหัสเดียวกัน! iterator ใช้ในทั้งสองกรณี"
"เป็นเพียงว่าการใช้งานถูกซ่อนอยู่ในfor-eachลูป โปรดทราบว่ารหัสทางด้านขวาไม่มี ข้อความ สีแดงเลย การใช้ตัววนซ้ำนั้นถูกซ่อนไว้อย่างสมบูรณ์"
" for-each loop ใช้สำหรับอ็อบเจกต์ใดๆ ที่สนับสนุนการวนซ้ำ กล่าวคือ คุณสามารถเขียนคลาสของคุณเอง เพิ่มเมธอด iterator ( )เข้าไป และใช้อ็อบเจกต์ใน โครงสร้าง for-each "
"ว้าว! แน่นอน ฉันไม่กระตือรือร้นที่จะเขียนคอลเลกชันและตัวทำซ้ำของตัวเอง แต่โอกาสยังคงดึงดูดใจ ฉันจะจดบันทึกไว้"
นอกจากนี้ยังมี iterator อีกประเภทที่ได้รับความนิยมซึ่งมีอินเทอร์เฟซของตัวเอง ฉันกำลังพูดถึงตัววนซ้ำสำหรับรายการเช่นListIterator
"โดยไม่คำนึงถึงการใช้งาน รายการจะรักษาลำดับขององค์ประกอบ ซึ่งทำให้การทำงานกับองค์ประกอบเหล่านี้ผ่าน iterator สะดวกขึ้นเล็กน้อย"
"นี่คือวิธีการของ อินเทอร์เฟซ ListIterator <E>:"
วิธี | คำอธิบาย |
---|---|
boolean hasNext() |
ตรวจสอบว่ามีองค์ประกอบอื่น ๆ อีกหรือไม่ |
E next() |
ส่งกลับองค์ประกอบถัดไป |
int nextIndex() |
ส่งกลับดัชนีขององค์ประกอบถัดไป |
void set(E e) |
เปลี่ยนค่าขององค์ประกอบปัจจุบัน |
boolean hasPrevious() |
ตรวจสอบว่ามีองค์ประกอบใดอยู่เบื้องหลังหรือไม่ |
E previous() |
ส่งกลับองค์ประกอบก่อนหน้า |
int previousIndex() |
ส่งกลับดัชนีขององค์ประกอบก่อนหน้า |
void remove() |
ลบองค์ประกอบปัจจุบัน |
void add(E e) |
เพิ่มองค์ประกอบที่ส่วนท้ายของรายการ |
"อีกนัยหนึ่ง ที่นี่เราสามารถเดินหน้าและถอยหลังได้ และยังมีฟีเจอร์เล็กๆ อีกสองสามอย่าง"
"อืม น่าสนใจดี ใช้ที่ไหน"
"สมมติว่าคุณต้องการเลื่อนไปมาในรายการที่เชื่อมโยง การดำเนินการรับจะค่อนข้างช้า แต่การดำเนินการถัดไป () จะเร็วมาก"
“อืม คุณทำให้ฉันเชื่อ ฉันจะจำมันไว้”
"ขอบคุณ เอลลี่!"
GO TO FULL VERSION