Sự khác biệt giữa iterator và iterable và cách sử dụng chúng là gì?


195

Tôi là người mới trong Java và tôi thực sự bối rối với iterator và iterable. Bất cứ ai có thể giải thích cho tôi và đưa ra một số ví dụ?

Câu trả lời:


199

An Iterablelà một đại diện đơn giản của một loạt các yếu tố có thể được lặp đi lặp lại. Nó không có bất kỳ trạng thái lặp như "phần tử hiện tại". Thay vào đó, nó có một phương thức tạo ra một Iterator.

An Iteratorlà đối tượng có trạng thái lặp. Nó cho phép bạn kiểm tra xem nó có nhiều phần tử hơn bằng cách sử dụng hasNext()và chuyển sang phần tử tiếp theo (nếu có) bằng cách sử dụng next().

Thông thường, một Iterablenên có thể tạo ra bất kỳ số Iterators hợp lệ .


điều đó có quan trọng nếu Iterableinteralhoặc externallặp lại hoặc có thể có bất kỳ trong số họ?
sakhunzai

90

Việc thực hiện Iterablelà một trong đó cung cấp một Iteratorchính nó:

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

Trình lặp là một cách đơn giản để cho phép một số người lặp qua một bộ sưu tập dữ liệu mà không có đặc quyền gán (mặc dù có khả năng loại bỏ).

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

Xem Javadoc .


16

Tôi sẽ trả lời câu hỏi đặc biệt là về ArrayList làm ví dụ để giúp bạn hiểu rõ hơn ..

  1. Giao diện lặp có thể buộc các lớp con của nó thực hiện phương thức trừu tượng 'iterator ()'.
public interface Iterable {
  ...
  abstract Iterator<T> iterator(); //Returns an 'Iterator'(not iterator) over elements of type T.
  ...
}
  1. Giao diện Iterator buộc các lớp con của nó thực hiện phương thức trừu tượng 'hasNext ()' và '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 thực hiện Danh sách, Danh sách mở rộng Bộ sưu tập và Bộ sưu tập mở rộng Iterable .. Đó là, bạn có thể thấy mối quan hệ như

    'Có thể lặp lại <- Bộ sưu tập <- Danh sách <- ArrayList'

. Và Iterable, Collection and List chỉ khai báo phương thức trừu tượng 'iterator ()' và ArrayList một mình thực hiện nó.

  1. Tôi sẽ hiển thị mã nguồn ArrayList với phương thức 'iterator ()' như sau để biết thêm thông tin chi tiết.

Phương thức 'iterator ()' trả về một đối tượng của lớp 'Itr', thực hiện '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. Một số phương thức hoặc lớp khác sẽ lặp lại các phần tử của các bộ sưu tập như ArrayList thông qua việc sử dụng Iterator (Itr).

Đây là một ví dụ đơn giản.

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);
    }
}

Bây giờ, nó đã rõ ràng? :)


Câu trả lời chính xác .!
Kavindu Dodanduwa

Tôi đã hiểu bài đăng này, nhưng nếu tôi muốn viết một phương thức có kiểu trả về Iterable<T>thì trong kịch bản này chúng ta cần thực hiện các bước nào? Xin đề nghị ví dụ đó cũng có.
Prasanna Sasne

12

Nếu một bộ sưu tập có thể lặp lại, thì nó có thể được lặp lại bằng cách sử dụng một trình vòng lặp (và do đó có thể được sử dụng trong một vòng lặp.) Trình vòng lặp là đối tượng thực tế sẽ lặp qua bộ sưu tập.


2
FYI a java.util.Collection luôn thực hiện java.util.Iterable.
Paul Draper

2
Có phải vậy không java.lang.Iterable?
ulab

Đó làjava.lang.Iterable
aldok

9

Việc thực hiện giao diện Iterable cho phép một đối tượng trở thành mục tiêu của câu lệnh "foreach".

class SomeClass implements Iterable<String> {}

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

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

Iterator là một giao diện, có triển khai để lặp qua các phần tử. Iterable là một giao diện cung cấp Iterator.


1
Nếu bất kỳ lớp nào đang thực hiện Iterable thì nó nên có một phương thức Iterator () trong đó phải không ??? Đúng nếu tôi đã sai lầm.
Chinmaya B

Đúng. Nó nên có phương thức chưa thực hiện của giao diện. Trong trường hợp này, nó là Iterator.
đại lý.smith

Cảm ơn cho một câu trả lời thông minh. Tôi đến đây để kiểm tra lại sự hiểu biết của tôi về Iterable vs Iterator. Bạn đã xác nhận nó. Tất cả các câu trả lời khác nói về cấu trúc, mà tôi đoán là ổn, nhưng không trả lời câu hỏi TẠI SAO tôi sử dụng cái này hơn cái kia.
EricGreg

Đối với tôi, đây là câu trả lời tốt nhất.
Sam

Tôi muốn biết lợi ích của mỗi vòng lặp đối với Chuỗi s: someClass. Vì someClass là đối tượng lớp java và s String ref. Theo những gì xơ gan người ta nên đi với loại thực hiện như vậy.
Neeraj

8

Việc xem xét quan trọng nhất là liệu mục trong câu hỏi có thể được duyệt qua nhiều lần hay không. Điều này là do bạn luôn có thể tua lại Iterable bằng cách gọi lại iterator (), nhưng không có cách nào để tua lại Iterator.


Tôi đã tự hỏi tại sao các lớp tập hợp không trực tiếp thực hiện giao diện Iterator (thay vì triển khai đối tượng Iterable và trả về Iterator). Câu trả lời này đã làm rõ rằng - trong trường hợp đó, không thể đi qua bộ sưu tập nhiều lần (và đồng thời bởi nhiều luồng). Đây là câu trả lời rất quan trọng.
SimpleDev

2

Như đã giải thích ở đây , The Iterable đã được giới thiệu để có thể sử dụng trong foreachvòng lặp. Một lớp thực hiện giao diện Iterable có thể được lặp lại.

Iterator là lớp quản lý việc lặp qua một Iterable . Nó duy trì trạng thái của chúng ta trong vòng lặp hiện tại và biết phần tử tiếp theo là gì và làm thế nào để có được nó.


2

Hãy xem xét một ví dụ có 10 quả táo. Khi nó thực hiện Iterable, nó giống như đặt từng quả táo vào các hộp từ 1 đến 10 và trả về một trình vòng lặp có thể được sử dụng để điều hướng.

Bằng cách thực hiện iterator, chúng ta có thể nhận được bất kỳ quả táo, quả táo nào trong các hộp tiếp theo, v.v.

Vì vậy, việc thực hiện iterable cung cấp cho một trình vòng lặp để điều hướng các phần tử của nó mặc dù để điều hướng, iterator cần phải được thực hiện.


1

Câu hỏi: Sự khác biệt giữa Iterable và Iterator?
Trả lời:

iterable: Nó liên quan đến vòng lặp forEach
iterator: Có liên quan đến Collection

Phần tử đích của sự cố vòng lặp forEach có thể lặp lại được.
Chúng ta có thể sử dụng Iterator để lấy từng đối tượng từ Bộ sưu tập

Có thể lặp lại trong gói java.ḷang
lặp lại trong lặp có mặt trong gói java.util

Chỉ chứa một phương thức iterator ()
Chứa ba phương thức hasNext (), next (), remove ()

Được giới thiệu trong phiên bản 1.5
Được giới thiệu trong phiên bản 1.2


1

Về cơ bản, cả hai đều có liên quan rất chặt chẽ với nhau.

Coi Iterator là một giao diện giúp chúng ta duyệt qua bộ sưu tập với sự trợ giúp của một số phương thức không xác định như hasNext (), next () và remove ()

Mặt khác, Iterable là một giao diện khác, nếu được triển khai bởi một lớp sẽ buộc lớp đó có thể lặp được và là mục tiêu cho cấu trúc For-Each. Nó chỉ có một phương thức có tên iterator () xuất phát từ chính giao diện Iterator.

Khi một bộ sưu tập có thể lặp lại, thì nó có thể được lặp lại bằng cách sử dụng một trình vòng lặp.

Để hiểu về chuyến thăm này:

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

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


1

Tôi biết đây là một câu hỏi cũ, nhưng đối với bất kỳ ai đọc câu hỏi này bị mắc kẹt với cùng một câu hỏi và người có thể bị choáng ngợp với tất cả các thuật ngữ, đây là một sự tương tự đơn giản, tốt để giúp bạn hiểu sự khác biệt giữa iterables và iterators:

Hãy nghĩ về một thư viện công cộng. Trường cũ. Với sách giấy. Vâng, đó là loại thư viện.

Một kệ đầy sách sẽ giống như một vòng lặp. Bạn có thể thấy dòng sách dài trong kệ. Bạn có thể không biết bao nhiêu, nhưng bạn có thể thấy rằng đó là một bộ sách dài.

Người thủ thư sẽ giống như người lặp. Anh ta có thể chỉ vào một cuốn sách cụ thể bất cứ lúc nào. Anh ta có thể chèn / xóa / sửa đổi / đọc sách tại vị trí mà anh ta chỉ. Ông chỉ, theo trình tự, đến từng cuốn sách mỗi lần bạn hét lên "tiếp theo!" cho anh ta. Vì vậy, thông thường bạn sẽ hỏi anh ta: "có Next không?", Và anh ta sẽ nói "có", mà bạn nói "tiếp theo!" và anh ấy sẽ chỉ vào cuốn sách tiếp theo. Anh ấy cũng biết khi nào anh ấy đến cuối kệ, để khi bạn hỏi: "có tiếp không?" anh ấy sẽ nói "không".

Tôi biết nó hơi ngớ ngẩn, nhưng tôi hy vọng điều này sẽ giúp.


0

Ngoài câu trả lời của ColinDSeeker .

Nói một cách đơn giản, IterableIterator là cả hai giao diện được cung cấp trong Bộ sưu tập Khung của Java.

Lặp lại

Một lớp phải thực hiện giao diện Iterable nếu nó muốn có một vòng lặp for- every để lặp lại bộ sưu tập của nó. Tuy nhiên, vòng lặp for-every chỉ có thể được sử dụng để xoay vòng bộ sưu tập theo hướng chuyển tiếp và bạn sẽ không thể sửa đổi các thành phần trong bộ sưu tập này . Nhưng, nếu tất cả những gì bạn muốn là đọc dữ liệu các phần tử, thì nó rất đơn giản và nhờ biểu thức lambda của Java, nó thường là một lớp lót. Ví dụ:

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

Lặp lại

Giao diện này cho phép bạn lặp lại một bộ sưu tập, thu thập và loại bỏ các yếu tố của nó. Mỗi lớp bộ sưu tập cung cấp một phương thức iterator () trả về một iterator để bắt đầu bộ sưu tập. Ưu điểm của giao diện này so với iterable là với giao diện này, bạn có thể thêm, sửa đổi hoặc xóa các thành phần trong bộ sưu tập . Nhưng, việc truy cập các phần tử cần nhiều mã hơn một chút so với lặp lại. Ví dụ:

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

Nguồn:

  1. Lặp lại tài liệu Java
  2. Trình lặp Java Doc

0

Iterable đã được giới thiệu để sử dụng cho mỗi vòng lặp trong java

public interface Collection<E> extends Iterable<E>  

Iteratorlà lớp quản lý việc lặp qua một Iterable. Nó duy trì trạng thái của chúng ta trong vòng lặp hiện tại và biết phần tử tiếp theo là gì và làm thế nào để có được nó.


Chào mừng bạn đến với SO, bạn luôn có thể thực hiện chuyến tham quan tại đây , để câu trả lời của bạn sẽ hữu ích và sạch sẽ hơn. Trong trường hợp của chúng tôi, câu hỏi là yêu cầu một lời giải thích liên quan đến hai lớp, nhưng câu trả lời của bạn khá khó hiểu thay vì làm sáng tỏ mọi thứ. Ngoài ra, hãy cố gắng giữ một ref, trong khi đăng đoạn trích từ các nguồn đã biết / hợp lệ / được chứng nhận, để làm cho câu trả lời của bạn cụ thể hơn.
AntJavaDev
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.