【发布时间】:2011-10-15 08:17:16
【问题描述】:
我是 Java 新手,我对迭代器和可迭代感到非常困惑。谁能给我解释一下并举一些例子?
【问题讨论】:
我是 Java 新手,我对迭代器和可迭代感到非常困惑。谁能给我解释一下并举一些例子?
【问题讨论】:
Iterable 是一系列可以迭代的元素的简单表示。它没有任何迭代状态,例如“当前元素”。相反,它有一种方法可以生成Iterator。
Iterator 是具有迭代状态的对象。它允许您使用hasNext() 检查它是否有更多元素,并使用next() 移动到下一个元素(如果有)。
通常,Iterable 应该能够生成任意数量的有效Iterators。
【讨论】:
Iterable 有interal 或external 迭代器或者可能有它们中的任何一个,这有关系吗?
Iterable 的实现是提供自身的Iterator:
public interface Iterable<T>
{
Iterator<T> iterator();
}
迭代器是一种简单的方法,它允许一些人在没有分配权限的情况下循环遍历数据集合(尽管可以删除)。
public interface Iterator<E>
{
boolean hasNext();
E next();
void remove();
}
见Javadoc。
【讨论】:
我将以ArrayList为例来回答这个问题,以帮助您更好地理解..
public interface Iterable { ... abstract Iterator<T> iterator(); //Returns an 'Iterator'(not iterator) over elements of type T. ... }
public interface Iterator { ... abstract boolean hasNext(); //Returns true if the iteration has more elements. abstract E next(); //Returns the next element in the iteration. ... }
'Iterable
。 而Iterable、Collection和List只是声明了抽象方法'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]; } ... } }
这是一个简单的例子。
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<T> 的方法,那么在这种情况下我们需要实现哪些步骤呢?也请提出这个例子。
如果集合是可迭代的,则可以使用迭代器对其进行迭代(因此可以在 for each 循环中使用。)迭代器是将迭代集合的实际对象。
【讨论】:
java.lang.Iterable吗?
java.lang.Iterable
我知道这是一个老问题,但是对于任何阅读本文的人来说,如果他们遇到同样的问题并且可能对所有术语感到不知所措,这里有一个很好的简单类比,可以帮助您理解迭代器和迭代器之间的区别:
想想公共图书馆。老套。用纸质书。是的,就是那种图书馆。
一个装满书的书架就像一个可迭代的。你可以看到书架上一排排的书。您可能不知道有多少,但您可以看到它是一本很长的书集。
图书馆员就像迭代器。他可以随时指向一本特定的书。他可以在他指向的那个位置插入/删除/修改/阅读这本书。每次您大喊“下一个!”时,他都会依次指向每本书。给他。所以,你通常会问他:“有下一个吗?”,他会说“是”,你会说“下一个!”他会指着下一本书。他也知道他什么时候到达了货架的尽头,所以当你问:“有下一个吗?”他会说“不”。
我知道这有点傻,但我希望这会有所帮助。
【讨论】:
实现 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的接口。
【讨论】:
最重要的考虑是该项目是否应该能够被多次遍历。这是因为您始终可以通过再次调用 iterator() 来回退 Iterable,但无法回退 Iterator。
【讨论】:
正如here 解释的那样,引入“Iterable”是为了能够在foreach 循环中使用。实现 Iterable 接口的类可以被迭代。
Iterator 是管理 Iterable 上的迭代的类。它维护我们在当前迭代中所处的状态,并且知道下一个元素是什么以及如何获取它。
【讨论】:
考虑一个有 10 个苹果的例子。 当它实现 Iterable 时,就像将每个苹果放入 1 到 10 的盒子中,并返回一个可用于导航的迭代器。
通过实现迭代器,我们可以得到任何苹果,苹果在下一个盒子等等。
所以实现 iterable 提供了一个迭代器来导航它的元素,尽管要导航,需要实现迭代器。
【讨论】:
问题:Iterable和Iterator的区别?
答:
iterable:与forEach循环有关
iterator: Is 与 Collection 有关
forEach 循环的目标元素应该是可迭代的。
我们可以使用Iterator从Collection中一一获取对象
可迭代存在于 java.ḷang 包中
java.util 包中存在迭代器
只包含一个方法iterator()
包含三个方法hasNext()、next()、remove()
在 1.5 版本中引入
1.2版本引入
【讨论】:
基本上来说,两者的关系都非常密切。
将 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
【讨论】:
Iterable被引入用于java中的每个循环
public interface Collection<E> extends Iterable<E>
Iterator 是管理Iterable 上的迭代的类。它维护我们在当前迭代中所处的状态,并且知道下一个元素是什么以及如何获取它。
【讨论】:
简单来说,Iterable和Iterator都是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
}
来源:
【讨论】: