0Pricing
Java Academy · บทเรียน

สัญญาของ Iterable และ Iterator

ทำความเข้าใจอินเทอร์เฟซ Iterable และ Iterator รวมถึงวิธีทำงานภายในของลูป for-each

สัญญาของ Iterable และ Iterator เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

Iterable และ Iterator

Iterable<T> และ Iterator<T> คืออินเทอร์เฟซที่ขับเคลื่อนลูปวนซ้ำสมาชิกของ Java การทำความเข้าใจทั้งสองแบบช่วยให้คุณสร้างโครงสร้างข้อมูลของตนเองที่ใช้กับลูปวนซ้ำสมาชิกได้

อินเทอร์เฟซ Iterable

Iterable<T> มีหนึ่งเมธอดคือ iterator() ซึ่งคืนค่าเป็น Iterator<T> คลาสใดก็ตามที่นำ Iterable ไปใช้สามารถใช้กับลูปวนซ้ำสมาชิกได้

// java.lang.Iterable<T>
interface Iterable<T> {
    Iterator<T> iterator();
    // default: forEach, spliterator (Java 8+)
}

// Any class implementing Iterable<T> works in for-each:
class Range implements Iterable<Integer> {
    private final int start, end;
    Range(int start, int end) { this.start = start; this.end = end; }

    public Iterator<Integer> iterator() {
        return new RangeIterator(); // defined separately
    }
}

อินเทอร์เฟซ Iterator

Iterator<T> มีสามเมธอด ได้แก่ hasNext(), next() และ remove() ซึ่งเป็นเมธอดทางเลือก

// java.util.Iterator<T>
interface Iterator<T> {
    boolean hasNext(); // true if more elements
    T next();          // returns next element, advances cursor
    default void remove() { throw new UnsupportedOperationException(); }
}

// How for-each desugars internally:
// for (T item : iterable) { use(item); }
// becomes:
Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
    T item = it.next();
    // use(item)
}

การคลี่รูปของลูปวนซ้ำสมาชิก

ลูปวนซ้ำสมาชิกเป็นเพียงรูปแบบไวยากรณ์ย่อของรูปแบบ Iterable/Iterator การทำความเข้าใจเรื่องนี้ช่วยให้คุณเขียน Iterable แบบกำหนดเองได้อย่างถูกต้อง

List<String> names = List.of("Alice", "Bob", "Charlie");

// For-each (readable way)
for (String name : names) {
    System.out.println(name);
}

// Equivalent explicit form
Iterator<String> it = names.iterator();
while (it.hasNext()) {
    String name = it.next();
    System.out.println(name);
}

สถานะตัวชี้ตำแหน่งของ Iterator

Iterator รักษาตัวชี้ตำแหน่ง ซึ่งเป็นตำแหน่งหนึ่งในลำดับ การเรียก next() จะเลื่อนตัวชี้ตำแหน่งไปข้างหน้า เมื่ออ่านครบแล้ว ตัววนซ้ำจะไม่สามารถเริ่มต้นใหม่ได้

List<Integer> nums = List.of(1, 2, 3);
Iterator<Integer> it = nums.iterator();

System.out.println(it.hasNext()); // true
System.out.println(it.next());    // 1
System.out.println(it.next());    // 2
System.out.println(it.next());    // 3
System.out.println(it.hasNext()); // false

try {
    it.next(); // NoSuchElementException
} catch (java.util.NoSuchElementException e) {
    System.out.println("No more elements!");
}

ConcurrentModificationException

การแก้ไขคอลเลกชันขณะวนซ้ำด้วยตัววนซ้ำที่เรียกใช้อย่างชัดแจ้ง โดยไม่ใช้ Iterator.remove() จะทำให้เกิด ConcurrentModificationException

List<String> list = new ArrayList<>(List.of("a", "b", "c", "d"));

// BAD: modifying collection during for-each
try {
    for (String s : list) {
        if ("b".equals(s)) list.remove(s); // ConcurrentModificationException!
    }
} catch (java.util.ConcurrentModificationException e) {
    System.out.println("Cannot modify during iteration!");
}

// GOOD: use Iterator.remove()
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if ("b".equals(it.next())) it.remove(); // safe
}
System.out.println(list); // [a, c, d]

Iterator หลายตัว

การเรียก iterator() แต่ละครั้งจะคืนค่าตัววนซ้ำใหม่ที่เป็นอิสระต่อกัน ตัววนซ้ำหลายตัวสามารถทำงานพร้อมกันกับคอลเลกชันเดียวกันได้

List<Integer> nums = List.of(1, 2, 3);

Iterator<Integer> a = nums.iterator();
Iterator<Integer> b = nums.iterator();

System.out.println(a.next()); // 1
System.out.println(b.next()); // 1 (independent cursor)
System.out.println(a.next()); // 2
System.out.println(b.next()); // 2

Iterable กับ Iterator

ความแตกต่างสำคัญ:

  • Iterable: แหล่งข้อมูลที่สร้างตัววนซ้ำได้ และสามารถวนซ้ำได้หลายครั้ง
  • Iterator: ตัวชี้ตำแหน่งเหนือลำดับ ใช้ได้ครั้งเดียวและมีสถานะ
// Iterable: reusable
List<String> list = List.of("x", "y");
for (String s : list) {} // OK
for (String s : list) {} // OK again — new iterator each time

// Iterator: single-use
Iterator<String> it = list.iterator();
while (it.hasNext()) it.next();
// for (String s : it) {} // compile error — Iterator is not Iterable!

เชิงปฏิบัติ: Iterable สำหรับบรรทัดในไฟล์แบบกำหนดเอง

ตัวอ่านไฟล์ที่นำ Iterable ไปใช้ เพื่อให้สามารถใช้ลูปวนซ้ำสมาชิกกับบรรทัดต่าง ๆ ในไฟล์ได้

import java.io.*;
import java.util.*;

class FileLines implements Iterable<String>, Closeable {
    private final BufferedReader reader;

    FileLines(String path) throws IOException {
        this.reader = new BufferedReader(new FileReader(path));
    }

    public Iterator<String> iterator() {
        return new Iterator<>() {
            private String nextLine = readNext();

            private String readNext() {
                try { return reader.readLine(); }
                catch (IOException e) { return null; }
            }

            public boolean hasNext() { return nextLine != null; }
            public String next() {
                String curr = nextLine;
                nextLine = readNext();
                return curr;
            }
        };
    }

    public void close() throws IOException { reader.close(); }
}

เมธอดเริ่มต้น forEach

Java 8 เพิ่มเมธอดเริ่มต้น forEach(Consumer) ให้กับ Iterable ซึ่งเป็นทางเลือกที่สะดวกแทนการเขียนลูปอย่างชัดแจ้ง

List<String> cities = List.of("New York", "London", "Tokyo");

// for-each loop
for (String city : cities) System.out.println(city);

// forEach with lambda
cities.forEach(city -> System.out.println(city));

// forEach with method reference (most concise)
cities.forEach(System.out::println);

// For transforming: use stream
cities.stream()
    .map(String::toUpperCase)
    .forEach(System.out::println);

รูปแบบ Iterator ในการใช้งานจริง

สรุปกรณีที่ควรนำ Iterable/Iterator ไปใช้:

  • โครงสร้างข้อมูลแบบกำหนดเอง เช่น ต้นไม้, Graph และรายการเชื่อมโยง
  • ลำดับแบบประเมินค่าเมื่อจำเป็น ซึ่งสร้างสมาชิกตามคำขอ
  • ลำดับที่อิงทรัพยากร เช่น บรรทัดในไฟล์ ตัวชี้ตำแหน่งฐานข้อมูล และคิวข้อความ

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ข้อยกเว้นใดจะเกิดขึ้นเมื่อแก้ไขคอลเลกชันขณะวนซ้ำด้วยลูปวนซ้ำสมาชิก

ทบทวน: ข้อกำหนดของ Iterable และ Iterator

ประเด็นสำคัญ:

  • Iterable มีหนึ่งเมธอดคือ iterator() ซึ่งทำให้รองรับลูปวนซ้ำสมาชิก
  • Iterator มี hasNext(), next() และ remove() ซึ่งเป็นทางเลือก
  • ลูปวนซ้ำสมาชิกเป็นรูปแบบไวยากรณ์ย่อของรูปแบบ Iterable/Iterator
  • เรียก iterator() หลายครั้งเพื่อรับตัวชี้ตำแหน่งใหม่ที่เป็นอิสระต่อกัน
  • อย่าแก้ไขคอลเลกชันระหว่างลูปวนซ้ำสมาชิก ให้ใช้ Iterator.remove() แทน
  • นำ Iterable ไปใช้กับโครงสร้างข้อมูลแบบกำหนดเองเพื่อรองรับลูปวนซ้ำสมาชิก

คำถามที่พบบ่อย

บทเรียน “สัญญาของ Iterable และ Iterator” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “สัญญาของ Iterable และ Iterator” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “สัญญาของ Iterable และ Iterator”

ทำความเข้าใจอินเทอร์เฟซ Iterable และ Iterator รวมถึงวิธีทำงานภายในของลูป for-each คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “สัญญาของ Iterable และ Iterator” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. สัญญาของ Iterable และ Iterator
  2. การสร้าง Iterator แบบกำหนดเอง
  3. ListIterator และการวนดูแบบสองทิศทาง
  4. Iterator แบบหยุดเร็วกับแบบปลอดภัย
← กลับไปที่ Java Academy