迭代器和传统for循环的主要区别,除了可以访问或不可以访问被迭代项的索引这一明显区别之外,就是使用迭代器从底层集合实现中抽象出客户端代码,请允许我详细说明。
当您的代码使用迭代器时
for(Item element : myCollection) { ... }
这种形式
Iterator<Item> iterator = myCollection.iterator();
while(iterator.hasNext()) {
Item element = iterator.next();
...
}
或此表单
for(Iterator iterator = myCollection.iterator(); iterator.hasNext(); ) {
Item element = iterator.next();
...
}
你的代码所说的是“我不关心集合的类型和它的实现,我只关心我能迭代它的元素”。这通常是更好的方法,因为它使您的代码更加解耦。
另一方面,如果使用经典for循环,如
for(int i = 0; i < myCollection.size(); i++) {
Item element = myCollection.get(i);
...
}
你的代码是说,我需要知道集合的类型,因为我需要以特定的方式迭代它的元素,我也可能会检查空值或根据迭代顺序计算一些结果。这使得你的代码更加脆弱,因为如果你收到的集合类型在任何时候发生变化,它将影响你的代码的工作方式。
总而言之,区别不在于速度或内存使用,而在于解耦代码,以便更灵活地应对变化。
迭代器优势:
next()
和previous()
向前和向后移动hasNext()
检查是否有更多元素Loop仅设计为迭代Collection
,因此如果您只想迭代Collection
,最好使用循环,例如for-each
,但如果您想要更多,则可以使用Iterator。
首先,有两种for循环,它们的行为非常不同。一种使用索引:
for (int i = 0; i < list.size(); i++) {
Thing t = list.get(i);
...
}
这种循环并不总是可行的。例如,列表有索引,但集合没有,因为它们是无序集合。
另一个,foreach循环在幕后使用迭代器:
for (Thing thing : list) {
...
}
这适用于所有类型的可迭代集合(或数组)
最后,您可以使用Iterator,它也适用于任何Iterable:
for (Iterator<Thing> it = list.iterator(); it.hasNext(); ) {
Thing t = it.next();
...
}
所以你实际上有3个循环可以比较。
您可以用不同的术语比较它们:性能,可读性,易出错性,能力。
迭代器可以执行前循环无法执行的操作。例如,您可以在迭代时移除元素(如果迭代器支持):
for (Iterator<Thing> it = list.iterator(); it.hasNext(); ) {
Thing t = it.next();
if (shouldBeDeleted(thing) {
it.remove();
}
}
列表还提供了可以在两个方向上迭代的迭代器。前循环仅从开始到结束进行迭代。
但是迭代器更危险,可读性更低。当您只需要foreach循环时,它是最具可读性的解决方案。使用迭代器,您可以执行以下操作,这将是一个错误:
for (Iterator<Thing> it = list.iterator(); it.hasNext(); ) {
System.out.println(it.next().getFoo());
System.out.println(it.next().getBar());
}
前循环不允许发生这样的错误。
使用索引访问元素对于由数组支持的集合来说效率稍高一些。但是,如果您改变主意并使用链接列表而不是 ArrayList,则突然间性能将非常糟糕,因为每次访问list.get(i)时
,链表将不得不循环遍历其所有元素,直到第i个元素。迭代器(以及前循环)没有这个问题。它始终使用最佳方式来循环访问给定集合的元素,因为集合本身具有自己的迭代器实现。
我的一般经验法则是:使用foreach循环,除非您确实需要Iterator的功能。当我需要访问循环中的索引时,我将只使用带数组的索引的for循环。
迭代器 乍看来,迭代器似乎很直观。但凑近了看,你会发现标准STL容器提供了四种不同的迭代器:iterator、const_iterator、reverse_iterator和const_reverse_iterator。很快你会注意到在这四种类型中,容器的insert和erase的某些形式只接受其中一种。那是问题的开始。为什么有四种迭代器?它们之间的关系是什么?它们可以互相转化吗?在调用算法和ST
For freedom Christ has set us free. Stand firm, therefore, and do not submit again to a yoke of slavery. 基督释放了我们,叫我们得以自由,所以要站立得稳,不要再被奴仆的轭挟制。(GALATIANS 5:1) 迭代器 迭代,对于读者已经不陌生了,曾有专门一节来讲述,如果印象不深,请复习《迭代》。
在Rust中,迭代器共分为三个部分:迭代器、适配器、消费者。 其中,迭代器本身提供了一个惰性的序列,适配器对这个序列进行诸如筛选、拼接、转换查找等操作,消费者则在前两者的基础上生成最后的数值集合。 但是,孤立的看这三者其实是没有意义的,因此,本章将在一个大节里联系写出三者。 迭代器、适配器、消费者
正如我们之前学到的,在Python中我们可以使用“for”循环来迭代出对象中的内容: >>> for value in [0, 1, 2, 3, 4, 5]: ... print(value) ... 0 1 4 9 16 25 可以使用“for”循环(迭代)的对象称为迭代器。因此,一个迭代器也就是一个遵循了迭代协议的对象。 内置函数“iter”可以用来创建一个迭代对象,这时使用“next”函数
我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list、tuple、dict、set、str等; 一类是generator,包括生成器和带yield的generator function。 这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。 可以使用isinstance()判断一个对象是否是Iterable对象: >>> from coll
从for循环讲起 我们在控制语句里学习了Rust的for循环表达式,我们知道,Rust的for循环实际上和C语言的循环语句是不同的。这是为什么呢?因为,for循环不过是Rust编译器提供的语法糖! 首先,我们知道Rust有一个for循环能够依次对迭代器的任意元素进行访问,即: for i in 1..10 { println!("{}", i); } 这里我们知道, (1..10) 其本身
问题内容: 在一次采访中有人问我,使用迭代器使用for循环有什么好处,或者使用循环比迭代器有什么好处? 任何人都可以回答这个问题,以便将来如果我遇到类似的问题,那么我可以回答 问题答案: 首先,有两种for循环,它们的行为非常不同。一种使用索引: 这种循环并非总是可能的。例如,列表具有索引,而集合没有索引,因为它们是无序集合。 另一个foreach循环在幕后使用Iterator: 这适用于每种It
主要内容:Ruby each 迭代器,语法,实例,Ruby collect 迭代器,语法,实例,实例简单来说:迭代(iterate)指的是重复做相同的事,所以迭代器(iterator)就是用来重复多次相同的事。 迭代器是集合支持的方法。存储一组数据成员的对象称为集合。在 Ruby 中,数组(Array)和哈希(Hash)可以称之为集合。 迭代器返回集合的所有元素,一个接着一个。在这里我们将讨论两种迭代器,each 和 collect。 Ruby each 迭代器 each 迭代器返回数组或哈希的