【问题标题】:What is the difference between iterator and iterable and how to use them?迭代器和可迭代之间有什么区别以及如何使用它们?
【发布时间】:2011-10-15 08:17:16
【问题描述】:

我是 Java 新手,我对迭代器和可迭代感到非常困惑。谁能给我解释一下并举一些例子?

【问题讨论】:

    标签: java iterator iterable


    【解决方案1】:

    Iterable 是一系列可以迭代的元素的简单表示。它没有任何迭代状态,例如“当前元素”。相反,它有一种方法可以生成Iterator

    Iterator 是具有迭代状态的对象。它允许您使用hasNext() 检查它是否有更多元素,并使用next() 移动到下一个元素(如果有)。

    通常,Iterable 应该能够生成任意数量的有效Iterators。

    【讨论】:

    • 如果Iterableinteralexternal 迭代器或者可能有它们中的任何一个,这有关系吗?
    • 解释得很好!!
    【解决方案2】:

    Iterable 的实现是提供自身的Iterator

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

    迭代器是一种简单的方法,它允许一些人在没有分配权限的情况下循环遍历数据集合(尽管可以删除)。

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

    Javadoc

    【讨论】:

      【解决方案3】:

      我将以ArrayList为例来回答这个问题,以帮助您更好地理解..

      1. Iterable 接口强制其子类实现抽象方法“iterator()”。
      public interface Iterable {
        ...
        abstract Iterator<T> iterator(); //Returns an 'Iterator'(not iterator) over elements of type T.
        ...
      }
      
      1. Iterator 接口强制其子类实现抽象方法“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

      。 而Iterable、Collection和List只是声明了抽象方法'iterator()',ArrayList单独实现。

      1. 我将展示带有 'iterator()' 方法的 ArrayList 源代码,如下所示以获取更多详细信息。

      'iterator()' 方法返回一个实现 'Iterator' 的类 'Itr' 的对象。

      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. 其他一些方法或类将通过使用迭代器 (Itr) 来迭代 ArrayList 等集合的元素。

      这是一个简单的例子。

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

      现在,清楚了吗? :)

      【讨论】:

      • 很好的答案。!
      • 我理解了这篇文章,但是如果我想编写一个返回类型为Iterable&lt;T&gt; 的方法,那么在这种情况下我们需要实现哪些步骤呢?也请提出这个例子。
      【解决方案4】:

      如果集合是可迭代的,则可以使用迭代器对其进行迭代(因此可以在 for each 循环中使用。)迭代器是将迭代集合的实际对象。

      【讨论】:

      • 仅供参考 java.util.Collection 始终实现 java.util.Iterable。
      • 不是java.lang.Iterable吗?
      • 我是java.lang.Iterable
      【解决方案5】:

      我知道这是一个老问题,但是对于任何阅读本文的人来说,如果他们遇到同样的问题并且可能对所有术语感到不知所措,这里有一个很好的简单类比,可以帮助您理解迭代器和迭代器之间的区别:

      想想公共图书馆。老套。用纸质书。是的,就是那种图书馆。

      一个装满书的书架就像一个可迭代的。你可以看到书架上一排排的书。您可能不知道有多少,但您可以看到它是一本很长的书集。

      图书馆员就像迭代器。他可以随时指向一本特定的书。他可以在他指向的那个位置插入/删除/修改/阅读这本书。每次您大喊“下一个!”时,他都会依次指向每本书。给他。所以,你通常会问他:“有下一个吗?”,他会说“是”,你会说“下一个!”他会指着下一本书。他也知道他什么时候到达了货架的尽头,所以当你问:“有下一个吗?”他会说“不”。

      我知道这有点傻,但我希望这会有所帮助。

      【讨论】:

      • 很好的例子.. 所以我们不能说...书架就是问题,我们有图书管理员来检查它。没有图书管理员的书架就没有价值,因为我们无法遍历它们
      【解决方案6】:

      实现 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的接口。

      【讨论】:

      • 如果有任何类正在实现 Iterable 它应该有一个 Iterator() 方法对吗???如果我错了,请纠正我。
      • 是的。它应该有接口的未实现方法。在这种情况下,它是迭代器。
      • 感谢您的明智回答。我来这里是为了仔细检查我对 Iterable vs Iterator 的理解。你确认了。所有其他答案都在谈论结构,我想这很好,但没有回答为什么我会使用一个而不是另一个的问题。
      • 对我来说,这是最好的答案。
      • 我想知道 For each loop for String s: someClass 有什么好处。由于 someClass 是 java 类对象和 s String ref。在什么情况下应该使用这种实现。
      【解决方案7】:

      最重要的考虑是该项目是否应该能够被多次遍历。这是因为您始终可以通过再次调用 iterator() 来回退 Iterable,但无法回退 Iterator。

      【讨论】:

      • 我想知道为什么集合类不直接实现 Iterator 接口(而不是实现 Iterable 并返回 Iterator 对象)。这个答案清楚地表明 - 在这种情况下,不可能多次遍历集合(也不能同时通过多个线程)。这是一个非常重要的答案。
      【解决方案8】:

      正如here 解释的那样,引入“Iterable”是为了能够在foreach 循环中使用。实现 Iterable 接口的类可以被迭代。

      Iterator 是管理 Iterable 上的迭代的类。它维护我们在当前迭代中所处的状态,并且知道下一个元素是什么以及如何获取它。

      【讨论】:

        【解决方案9】:

        考虑一个有 10 个苹果的例子。 当它实现 Iterable 时,就像将每个苹果放入 1 到 10 的盒子中,并返回一个可用于导航的迭代器。

        通过实现迭代器,我们可以得到任何苹果,苹果在下一个盒子等等。

        所以实现 iterable 提供了一个迭代器来导航它的元素,尽管要导航,需要实现迭代器。

        【讨论】:

          【解决方案10】:

          问题:Iterable和Iterator的区别?
          答:

          iterable:与forEach循环有关
          iterator: Is 与 Collection 有关

          forEach 循环的目标元素应该是可迭代的。
          我们可以使用Iterator从Collection中一一获取对象

          可迭代存在于 java.ḷang 包中
          java.util 包中存在迭代器

          只包含一个方法iterator()
          包含三个方法hasNext()、next()、remove()

          在 1.5 版本中引入
          1.2版本引入

          【讨论】:

            【解决方案11】:

            基本上来说,两者的关系都非常密切。

            Iterator 视为一个接口,它可以帮助我们借助一些未定义的方法(如 hasNext()、next() 和 remove())遍历集合

            另一方面,Iterable 是另一个接口,如果由一个类实现,它会强制该类为 Iterable,并且是 For-Each 构造的目标。 它只有一个名为 iterator() 的方法,它来自 Iterator 接口本身。

            当一个集合是可迭代的,那么它就可以使用一个迭代器进行迭代。

            如需了解,请访问这些:

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

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

            【讨论】:

              【解决方案12】:

              Iterable被引入用于java中的每个循环

              public interface Collection<E> extends Iterable<E>  
              

              Iterator 是管理Iterable 上的迭代的类。它维护我们在当前迭代中所处的状态,并且知道下一个元素是什么以及如何获取它。

              【讨论】:

              • 欢迎来到SO,您可以随时参加here的游览,这样您的回答会更有帮助和更干净。在我们的例子中,问题是要求对这两个类进行解释,但是您的回答很混乱,而不是把事情弄清楚。在发布来自已知/有效/认证来源的 sn-ps 时,请尝试保留参考,以使您的答案更加具体。
              【解决方案13】:

              除了ColinDSeeker 的答案。

              简单来说,IterableIterator都是Java Collection Framework中提供的接口。

              可迭代

              如果一个类想要有一个 for-each 循环来迭代它的集合,它必须实现 Iterable 接口。但是,for-each 循环只能用于向前循环遍历集合,您将无法修改此集合中的元素。但是,如果您只想读取元素数据,那么它非常简单,并且由于 Java lambda 表达式,它通常是一个衬垫。例如:

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

              迭代器

              此接口使您能够遍历集合,获取和删除其元素。每个集合类都提供了一个 iterator() 方法,该方法将迭代器返回到集合的开头。该接口优于可迭代接口的优点在于,使用该接口您可以添加、修改或删除集合中的元素。但是,访问元素需要比可迭代更多的代码。例如:

              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

              【讨论】:

                猜你喜欢
                • 2020-04-14
                • 1970-01-01
                • 2014-12-05
                • 2012-02-10
                • 2010-11-04
                • 2018-01-28
                • 2012-06-14
                • 2011-07-17
                相关资源
                最近更新 更多