当前位置: 首页 > 面试题库 >

“无限”迭代器设计不好吗?

欧阳向文
2023-03-14
问题内容

提供Iterator“无限”的实现通常被认为是不好的做法吗?即在哪里对hasNext()always(*)的调用返回true?

通常我会说“是”,因为调用代码可能行为异常,但是在下面的实现中,hasNext()除非调用者从初始化迭代器的列表中删除所有元素,否则它将返回true。即
存在终止条件 。您认为这是合法使用Iterator吗?尽管我认为有人可以辩称这是不直观的,但它似乎并未违反合同。

public class CyclicIterator<T> implements Iterator<T> {
  private final List<T> l;
  private Iterator<T> it;

  public CyclicIterator<T>(List<T> l) {
    this.l = l;
    this.it = l.iterator();
  }

  public boolean hasNext() {
    return !l.isEmpty();
  }

  public T next() {
    T ret;

    if (!hasNext()) {
      throw new NoSuchElementException();
    } else if (it.hasNext()) {
      ret = it.next();
    } else {
      it = l.iterator();
      ret = it.next();
    }

    return ret;
  }

  public void remove() {
    it.remove();
  }
}

(书呆子)编辑

有人评论了如何Iterator使用an来从无界序列(例如斐波那契序列)生成值。但是,Java Iterator文档指出,迭代器为:

集合上的迭代器。

现在您可以争论斐波那契数列是一个无限集合,但是在Java中,我将集合等同于java.util.Collection接口,该接口提供了诸如size()暗示必须对集合进行绑定的方法。因此,将其Iterator用作无界序列的值生成器是否合法?


问题答案:

我认为这 完全是合法的 - Iterator仅仅是“东西”的流。为什么必须限制流?

许多其他语言(例如Scala)具有内置于其中的无限流的概念,并且可以对其进行迭代。例如,使用scalaz

scala> val fibs = (0, 1).iterate[Stream](t2 => t2._2 -> (t2._1 + t2._2)).map(_._1).iterator
fibs: Iterator[Int] = non-empty iterator

scala> fibs.take(10).mkString(", ") //first 10 fibonnacci numbers
res0: String = 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

编辑: 就最不惊奇的原则而言,我认为这完全取决于上下文。 例如,我希望该方法返回什么?

public Iterator<Integer> fibonacciSequence();


 类似资料:
  • 迭代器(Iterator) Intent 提供一种顺序访问聚合对象元素的方法,并且不暴露聚合对象的内部表示。 Class Diagram Aggregate 是聚合类,其中 createIterator() 方法可以产生一个 Iterator; Iterator 主要定义了 hasNext() 和 next() 方法; Client 组合了 Aggregate,为了迭代遍历 Aggregate,也

  • 问题 你在代码中使用 while 循环来迭代处理数据,因为它需要调用某个函数或者和一般迭代模式不同的测试条件。 能不能用迭代器来重写这个循环呢? 解决方案 一个常见的IO操作程序可能会想下面这样: CHUNKSIZE = 8192 def reader(s): while True: data = s.recv(CHUNKSIZE) if data ==

  • 问题内容: 此代码将导致无限循环的机会是什么? 实际上,这会导致无限循环。我的怀疑是因为我没有服用,是真的吗? 问题答案: 是。除非您不打电话,否则它将永远不会继续进行下一项。Beause 将返回您已在列表/集中添加的对象。

  • 介绍 迭代器模式(Iterator):提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示。 迭代器的几个特点是: 访问一个聚合对象的内容而无需暴露它的内部表示。 为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。 遍历的同时更改迭代器所在的集合结构可能会导致问题(比如C#的foreach里不允许修改item)。 正文 一般的迭代,我们至少要有2个方

  • 本文向大家介绍javascript设计模式之迭代器模式,包括了javascript设计模式之迭代器模式的使用技巧和注意事项,需要的朋友参考一下 迭代器模式分为内部迭代器和外部迭代器,内部迭代器就是在函数内部定义好迭代的规则,它完全接手整个迭代的过程,外部只需一次初始调用。 内部迭代器 以下自行实现的类似jquery中$.each()的each()函数就是内部迭代器 内部迭代器在调用时非常方便,但是

  • 看看我制作的以下类: 以及它在以下方面的用法: 如果我使用,可能令人惊讶的是,我将永远得不到无限流。 相反,代码将在底层方法中创建时永远循环。 到目前为止,这是纯理论上的,但如果我想首先跳过无限流中的前x个数字,然后用最后的y个数字来限制它,我可以明确地理解它的必要性,如下所示: 代码不会返回一个结果,应该怎么做呢?