我们还需要Iterator设计模式吗?

时间:2011-02-28 09:51:53

标签: c# java design-patterns

你好 我正在学习设计模式,我找到了Iterator。 我们还需要使用吗? 由于我们有集合,我很困惑为什么我们仍然需要Iterator设计模式。

由于

9 个答案:

答案 0 :(得分:7)

事实上,集合在两种语言中都主动使用迭代器。每当你遍历集合的元素时,都会涉及某种迭代器,即使你没有在代码中明确地看到它。我用Java来举例,因为我对它更熟悉。

在Java 5之前迭代集合的首选习惯用法 - 明确使用Iterator

for (Iterator i = c.iterator(); i.hasNext(); ) {
  doSomething((Element) i.next()); // (No generics before 1.5)
}

从Java 5开始:

for (Element e : elements) {
  doSomething(e);
}

后者导致实际上相同的字节码,在幕后使用Iterator

答案 1 :(得分:7)

IEnumerator<T>是一个迭代器,IEnumerable<T>创建它们。几乎所有馆藏都实施IEnumerable<T>

它是Linq-To-Objects的核心,这是C#3的核心功能之一。因此迭代器在现代C#中非常重要。

C#3还引入了一种特殊的语言功能,允许您使用yield return语法轻松实现迭代器。

foreach也基于迭代器。

答案 2 :(得分:2)

IEnumerable 接口正是迭代器模式:)

答案 3 :(得分:2)

在Java中,Iterator有其他用途,特别是Iterator.remove()仍然有用。

答案 4 :(得分:2)

是的,我们仍然需要迭代器!

1)在没有迭代器的情况下,在链接列表中循环O(n^2)

for (int i = 0; i < list.size(); i++)
  list.get(i).foo();

要进入元素#5,列表从head元素开始,后跟4个链接。要在下一个循环中到达元素#6,它会再次从头开始,跟随所有相同的链接(加一)。迭代器很聪明,可以记住最后一个位置,给出O(n)。快得多!

2)size()存在问题。有时候你还不知道它的大小。一些生产者线程可能正在添加元素,而另一个线程想要开始阅读。如果它首先需要大小,(for(i=0;i<size;i++))它在生成器线程完成之前无法启动。

一个集合可能太大了,元素不能完全适合内存。迭代器一次只提供对一个元素的访问,因此它只需要适合一个元素。

3)如何遍历树的所有元素?要编写代码bug免费并不那么简单。幸运的是,你可以获得树中所有元素的迭代器,并愉快地遍历它们,而不必担心订单或任何事情。

迭代器隐藏了元素的存储方式,只提供了访问,这是一个很好的抽象。

答案 5 :(得分:1)

迭代器和集合的不同之处在于集合本质上是持有项目,而迭代器只是逐个检索项目,而不包含在其中。

例如,IDataReader是数据库项的迭代器,您可以拥有一个IEnumerable迭代器来处理文件系统中的目录条目,以及一个集合的迭代器。

答案 6 :(得分:1)

在许多情况下,迭代未知数量的项目而不是在集合中收集所有项目更有效。以下是几个示例,说明为什么迭代更有效。在某些情况下甚至无法使用集合。

  • 该列表基于缓慢的资源,无法一次性提供所有项目。 (数据库读者,文件,网络资料,计算)
  • 源只允许前向游标(如磁带,数据库游标,服务器客户端流的东西)
  • 正在生成列表
  • 列表非常长,不能一次保存在内存中
  • 您正在使用链接列表,其中获取下一个元素比在索引i获取元素更有效。
  • 获取源列表后,应根据该列表创建新结果。例如,应该过滤和转换源列表。将结果保存在新列表中时效率不高,只有部分值可以重复使用。

最后一个例子涉及linq或类似的方法,其中可以有效地转换复杂的对象结构。 此外,使用for循环来处理所有项目而不是使用foreach更加复杂。

答案 7 :(得分:0)

Java和C#集合使用底层的迭代器模式。它几乎是可变集合的必需品。

如果您选择使用持久性集合(例如,功能Java库中提供的那些集合),则不再需要迭代器模式。

答案 8 :(得分:0)

集合为一组值封装了不同类型的组织 - 如集合,列表数组等。

Iterators封装/表示的是这些 -

  1. 以类型安全的方式引用集合中任何一个存储的项目。
  2. 即使我有一个字符串列表,我的内部列表     实现将使用包含String值的对象     以及下一个+上一个项目。迭代器隐藏了这些内部     可能已经暴露的对象。

    1. 迭代它们的方法 -
    2. 取决于代表的实际对象的类型     迭代它们的迭代器可能会有很大的不同。例如     数组你会去下一个索引。但是你需要的列表     访问下一个或上一个项目引用。

      1. 常见的操作,如前一个和下一个项目。

      2. 其他信息,如迭代器特性,让您知道使用迭代器支持的移动类型

      3. 因此,我们现在可以拥有一个可以应用于任何一个的单一访问循环,而不是为vector提供一个自定义for循环,而另一个自定义循环用于访问map元素和另一个用于访问列表集合的自定义循环。这些类型。

        事实上,这使得基于模板的算法成为可能,因为他们现在只需要专注于对内容或集合的处理,并忽略传递给它们的集合类型。

        我甚至会说迭代器模式是最简单和基本的项目,像STL这样的模板集合的整个概念从这个项目开始。