ความแตกต่างระหว่างตัววนซ้ำกับตัววนซ้ำและวิธีใช้พวกมันคืออะไร?


197

ฉันใหม่ใน Java และฉันสับสนจริงๆกับ iterator และ iterable ใครสามารถอธิบายให้ฉันและยกตัวอย่างได้บ้าง

คำตอบ:


201

An Iterableเป็นการแทนค่าง่าย ๆ ของชุดขององค์ประกอบที่สามารถทำซ้ำได้ ไม่มีสถานะการวนซ้ำใด ๆ เช่น "องค์ประกอบปัจจุบัน" Iteratorแต่มันมีวิธีการหนึ่งที่ก่อให้เกิด

An Iteratorคือวัตถุที่มีสถานะการวนซ้ำ ซึ่งช่วยให้คุณตรวจสอบว่ามีองค์ประกอบมากขึ้นโดยใช้hasNext()และการย้ายไปยังองค์ประกอบถัดไป (ถ้ามี) next()โดยใช้

โดยทั่วไปแล้ว a Iterableควรจะสามารถสร้างจำนวนที่ถูกต้องIteratorของ s ใด ๆ


จะเป็นเช่นไรถ้าIterableมีinteralหรือexternalวนซ้ำหรือเป็นไปได้ที่จะมีหนึ่งในนั้นหรือไม่
sakhunzai

91

การดำเนินการของIterableเป็นหนึ่งที่ให้Iteratorตัวเอง:

public interface Iterable<T>
{
    Iterator<T> iterator();
}

ตัววนซ้ำเป็นวิธีง่ายๆในการอนุญาตให้บางคนวนลูปผ่านการรวบรวมข้อมูลโดยไม่มีสิทธิ์การมอบหมาย (แม้ว่าจะมีความสามารถในการลบ)

public interface Iterator<E>
{
    boolean hasNext();
    E next();
    void remove();
}

ดูJavadoc


17

ฉันจะตอบคำถามโดยเฉพาะเกี่ยวกับ ArrayList เป็นตัวอย่างเพื่อช่วยให้คุณเข้าใจดีขึ้น ..

  1. ส่วนต่อประสาน Iterable บังคับให้ subclasses ของมันใช้ method นามธรรม 'iterator ()'
public interface Iterable {
  ...
  abstract Iterator<T> iterator(); //Returns an 'Iterator'(not iterator) over elements of type T.
  ...
}
  1. ส่วนต่อประสาน Iterator บังคับให้คลาสย่อยนั้นใช้เมธอด abstract 'hasNext ()' และ 'next ()'
public interface Iterator {
  ...
  abstract boolean hasNext(); //Returns true if the iteration has more elements.
  abstract E next();          //Returns the next element in the iteration.
  ...
}
  1. ArrayList ใช้ List, List ขยาย Collection และ Collection ขยาย Iterable .. นั่นคือคุณสามารถเห็นความสัมพันธ์เช่น

    'Iterable <- ชุดรวม <- รายการ <- ArrayList'

. และ Iterable, การรวบรวมและรายการเพียงประกาศวิธีนามธรรม 'iterator ()' และ ArrayList เพียงอย่างเดียวใช้มัน

  1. ฉันจะแสดงซอร์สโค้ด ArrayList ด้วยเมธอด 'iterator ()' ดังต่อไปนี้สำหรับข้อมูลรายละเอียดเพิ่มเติม

เมธอด 'iterator ()' ส่งคืนออบเจ็กต์ของคลาส 'Itr' ซึ่งใช้ 'Iterator'

public class ArrayList<E> ... implements List<E>, ...
{
  ...
  public Iterator<E> iterator() {
              return new Itr();
  }


  private class Itr implements Iterator<E> {
          ...

          public boolean hasNext() {
              return cursor != size;
          }
          @SuppressWarnings("unchecked")
          public E next() {
              checkForComodification();
              int i = cursor;
              if (i >= size)
                  throw new NoSuchElementException();
              Object[] elementData = ArrayList.this.elementData;
              if (i >= elementData.length)
                  throw new ConcurrentModificationException();
              cursor = i + 1;
              return (E) elementData[lastRet = i];
          }
          ...
  }
}
  1. วิธีการหรือคลาสอื่นจะทำซ้ำองค์ประกอบของคอลเลกชันเช่น ArrayList ผ่านการใช้ Iterator (Itr)

นี่คือตัวอย่างง่ายๆ

public static void main(String[] args) {

    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    list.add("e");
    list.add("f");

    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
        String string = iterator.next();
        System.out.println(string);
    }
}

ตอนนี้มันชัดเจนหรือไม่ :)


คำตอบที่ดี!
Kavindu Dodanduwa

ฉันเข้าใจโพสต์นี้ แต่จะทำอย่างไรถ้าฉันต้องการเขียนวิธีที่มีชนิดส่งคืนIterable<T>ในสถานการณ์นี้เราจำเป็นต้องใช้ขั้นตอนใดบ้าง โปรดแนะนำตัวอย่างนั้นด้วย
Prasanna Sasne

12

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


2
FYI a java.util.Collection ใช้ java.util.Iterable เสมอ
Paul Draper

2
ไม่ใช่java.lang.Iterableเหรอ
ulab

มันjava.lang.Iterable
aldok

9

การนำอินเตอร์เฟส Iterable ไปใช้ทำให้วัตถุเป็นเป้าหมายของคำสั่ง "foreach"

class SomeClass implements Iterable<String> {}

class Main 
{
  public void method()
  {
     SomeClass someClass = new SomeClass();
     .....

    for(String s : someClass) {
     //do something
    }
  }
}

Iterator เป็นอินเทอร์เฟซซึ่งมีการใช้งานสำหรับวนซ้ำองค์ประกอบ Iterable เป็นอินเตอร์เฟสที่ให้ Iterator


1
ถ้าคลาสใดที่ใช้ Iterable มันควรจะมีเมธอด Iterator () ในนั้นใช่มั้ย ??? ถูกต้องฉันถ้าฉันผิด
Chinmaya B

ใช่. มันควรจะมีวิธีการไม่ใช้ส่วนต่อประสาน ในกรณีนี้คือ Iterator
agent.smith

ขอบคุณสำหรับคำตอบที่ชาญฉลาด ฉันมาที่นี่เพื่อตรวจสอบความเข้าใจของฉันเกี่ยวกับ Iterable กับ Iterator อีกครั้ง คุณยืนยันมัน คำตอบอื่น ๆ ทั้งหมดพูดคุยเกี่ยวกับโครงสร้างซึ่งฉันเดาว่าใช้ได้ แต่ไม่ตอบคำถามที่ว่าทำไมฉันถึงต้องใช้อีกแบบหนึ่ง
EricGreg

สำหรับฉันนี่คือคำตอบที่ดีที่สุด
แซม

ฉันต้องการที่จะรู้ว่าสิ่งที่เป็นประโยชน์ของสำหรับแต่ละวงสำหรับ String s: someClass เนื่องจาก someClass เป็นอ็อบเจ็กต์คลาส Java และ s String ref ภายใต้สภาวะใดที่ควรมีการใช้งานเช่นนั้น
Neeraj

8

การพิจารณาที่สำคัญที่สุดคือว่ารายการที่เป็นปัญหาควรสามารถสำรวจได้มากกว่าหนึ่งครั้งหรือไม่ นี่เป็นเพราะคุณสามารถย้อนกลับ Iterable ได้ตลอดเวลาโดยเรียก iterator () อีกครั้ง แต่ไม่มีวิธีที่จะย้อนกลับ Iterator


ฉันสงสัยว่าทำไมคลาสของคอลเล็กชันไม่ได้ใช้อินเตอร์เฟส Iterator โดยตรง (แทนที่จะใช้ Iterable และส่งคืนออบเจ็กต์ Iterator) คำตอบนี้ทำให้เห็นได้ชัดว่า - ในกรณีนี้จะไม่สามารถทำการรวบรวมหลาย ๆ ครั้ง (และพร้อมกันหลายเธรด) นี่เป็นคำตอบที่สำคัญมาก
simpleDev

2

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

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


2

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

ด้วยการใช้ตัววนซ้ำเราสามารถรับแอปเปิ้ลแอปเปิ้ลในกล่องถัดไปเป็นต้น

ดังนั้นการใช้ iterable จึงทำให้ iterator นำทางองค์ประกอบของมันแม้ว่าจะไปทาง iterator ก็จำเป็นต้องนำไปปฏิบัติ


1

คำถาม: ความแตกต่างระหว่าง Iterable และ Iterator?
ตอบ:

iterable: มันเกี่ยวข้องกับ forEach loop
iterator: เกี่ยวข้องกับ Collection

องค์ประกอบเป้าหมายของ foreach loop shouble นั้นสามารถทำซ้ำได้
เราสามารถใช้ Iterator เพื่อรับวัตถุทีละรายการจากคอลเล็กชัน

Iterable present ในjava.ḷang package
Iterator มีอยู่ใน java.util package

มี iterator วิธีเดียวเท่านั้น () มี
สามวิธีมี hasNext () ถัดไป (), remove ()

แนะนำในรุ่น 1.5
เปิดตัวในรุ่น 1.2


1

โดยพื้นฐานแล้วทั้งคู่มีความสัมพันธ์กันอย่างใกล้ชิด

พิจารณาIteratorเป็นอินเทอร์เฟซที่ช่วยให้เราผ่านการรวบรวมด้วยความช่วยเหลือของวิธีการที่ไม่ได้กำหนดเช่นhasNext () ถัดไป () และลบ ()

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

เมื่อมีการทำซ้ำคอลเลกชันก็สามารถทำซ้ำได้โดยใช้ตัววนซ้ำ

เพื่อความเข้าใจโปรดไปที่:

ITERABLE: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Iterable.java

ITERATOR http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Iterator.java


1

ฉันรู้ว่านี่เป็นคำถามเก่า แต่สำหรับใครก็ตามที่อ่านคำถามนี้ซึ่งติดอยู่กับคำถามเดียวกันและใครบ้างที่อาจถูกครอบงำด้วยคำศัพท์ทั้งหมดนี่คือการเปรียบเทียบที่ดีและเรียบง่ายเพื่อช่วยให้คุณเข้าใจความแตกต่างระหว่าง iterables และ iterators นี้:

นึกถึงห้องสมุดสาธารณะ โรงเรียนเก่า. พร้อมหนังสือกระดาษ ใช่แล้วห้องสมุดประเภทนั้น

ชั้นวางหนังสือที่เต็มไปด้วยความน่าสนใจ คุณสามารถดูหนังสือที่มีแถวยาวในหิ้ง คุณอาจไม่รู้ว่ามีจำนวนเท่าไหร่ แต่คุณสามารถเห็นได้ว่ามันเป็นหนังสือที่มีการสะสมมายาวนาน

บรรณารักษ์จะเป็นเหมือนตัววนซ้ำ เขาสามารถชี้ไปที่หนังสือเล่มใดเล่มหนึ่งได้ตลอดเวลา เขาสามารถแทรก / ลบ / แก้ไข / อ่านหนังสือในตำแหน่งที่เขาชี้ เขาชี้ไปที่หนังสือแต่ละเล่มในแต่ละครั้งที่คุณตะโกน "ถัดไป!" ตามลำดับ ให้เขา. ปกติแล้วคุณจะถามเขาว่า: "มีต่อไปหรือไม่" และเขาจะพูดว่า "ใช่" ซึ่งคุณจะพูดว่า "ต่อไป!" และเขาจะชี้ไปที่หนังสือเล่มต่อไป นอกจากนี้เขายังรู้ว่าเมื่อถึงจุดสิ้นสุดของชั้นวางดังนั้นเมื่อคุณถามว่า: "มีต่อไป" เขาจะพูดว่า "ไม่"

ฉันรู้ว่ามันค่อนข้างโง่ แต่ฉันหวังว่านี่จะช่วยได้


0

นอกจากคำตอบของColinDและผู้สมัครแล้ว

กล่าวง่ายๆว่าIterableและIteratorเป็นทั้งสองอินเตอร์เฟสที่มีให้ใน Java Framework Collection

Iterable

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

iterableElements.forEach (x -> System.out.println(x) );

iterator

อินเทอร์เฟซนี้ช่วยให้คุณสามารถย้ำผ่านคอลเลกชันรับและลบองค์ประกอบ คลาสคอลเล็กชันแต่ละคลาสจะมีเมธอดiterator ()ที่ส่งคืนตัววนซ้ำไปยังจุดเริ่มต้นของคอลเลกชัน ประโยชน์ของอินเตอร์เฟซนี้มากกว่า iterable เป็นที่ที่มีอินเตอร์เฟซนี้คุณสามารถเพิ่มแก้ไขหรือลบองค์ประกอบในคอลเลกชัน แต่การเข้าถึงองค์ประกอบจำเป็นต้องใช้รหัสมากกว่า iterable เล็กน้อย ตัวอย่างเช่น:

for (Iterator i = c.iterator(); i.hasNext(); ) {
       Element e = i.next();    //Get the element
       System.out.println(e);    //access or modify the element
}

แหล่งที่มา:

  1. Java Doc Iterable
  2. Java Doc Iterator

0

Iterable ถูกนำมาใช้ในแต่ละวงในจาวา

public interface Collection<E> extends Iterable<E>  

IteratorIterableเป็นชั้นที่จัดการย้ำกว่า มันยังคงสถานะที่เราอยู่ในการวนซ้ำปัจจุบันและรู้ว่าองค์ประกอบต่อไปคืออะไรและทำอย่างไร


ยินดีต้อนรับสู่ SO คุณสามารถทัวร์ที่นี่ได้เสมอเพื่อที่คำตอบของคุณจะเป็นประโยชน์และสะอาดยิ่งขึ้น ในกรณีของเราคำถามกำลังขอคำอธิบายเกี่ยวกับสองชั้นเรียน แต่คำตอบของคุณค่อนข้างสับสนแทนการล้างสิ่งต่าง ๆ ออกไป และพยายามเก็บไว้อ้างอิงขณะโพสต์ตัวอย่างจากแหล่งที่รู้จัก / ถูกต้อง / รับรองเพื่อทำให้คำตอบของคุณชัดเจนยิ่งขึ้น
AntJavaDev
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.