9

我最近读了一本书“Java 教程”第 3 版。如图所示,它讨论了内部类的实现。

在第 3 段中,它说“Stack 类本身不应该实现 Iterator 接口,因为......”。

我找不到任何 Stack 类不应该实现 Iterator 的原因。给出的理由并不普遍。

你能解释一下吗?

内部类 内部类

4

5 回答 5

9

从根本上说,迭代器是有状态的——它需要知道在集合中指向的位置。这不属于集合本身的一部分——给出的解释是正确的……完全有可能有两个独立的迭代器对象,迭代同一个集合对象。如果集合本身实现了 Iterator 接口,您将如何建模?这是可能的(例如,创建一个集合的新实例,该实例又持有对原始集合的引用),但这真的很难看。

这里有单独的问题:

  • 数据的收集
  • 位于集合中的光标

单独的关注点=>单独的类。

说服自己这一点的最简单方法可能是尝试实现自己的集合 - 然后拥有多个迭代器。例如,您可能想尝试:

List<String> foo = new MyListImplementation<String>();
foo.add("a");
foo.add("b");

// The enhanced for loop uses Iterable/Iterator for non-arrays
for (String x : foo) {
    for (String y : foo) {
        System.out.println(x + " " + y);
    }
}

应该打印出来:

a a
a b
b a
b b

尝试在没有两个类的情况下实现它,看看你是怎么做的,记住关注点分离。

于 2013-04-18T16:56:31.997 回答
4

堆栈不应该实现 Iterator 本身,因为那样您一次只能有一个迭代器,并且迭代堆栈会更改堆栈。

对于后一个问题,请注意嵌套类有一个“currentItem”字段。该字段需要在“堆栈”中,并且在调用 next() 时会更改。迭代集合不应该改变集合。

第一个问题更严重:假设两个人在堆栈上进行迭代(或者一个方法希望在堆栈上创建两个迭代器)。然后如果iterator()返回this,这两个迭代器将是同一件事。召唤next()一个会移动另一个。混乱。

于 2013-04-18T16:58:02.967 回答
2

AStack不能是它自己的Iterator,因为 Stack 支持多个 Iterator。

您可能希望多次迭代堆栈。这些迭代可能发生在不同的时间,甚至是同一时间。同时多次迭代显然需要多个对象。不同时间的多次迭代需要多个对象,因为 Iterator 接口不支持返回起点。

于 2013-04-18T16:55:37.203 回答
1

我能想到的原因有两个。

多种类型的迭代器

您可能需要以不同方式迭代的多种类型的迭代器。例如,前向迭代器和后向迭代器(从容器的末尾迭代到开头)。

迭代器的多个实例

如果你有一个多遍算法和/或嵌套循环,每个循环可能需要它自己的迭代器来跟踪它在容器中的位置,独立于其他迭代器。


Iterator使用类中实现的接口来支持这些功能即使不是不可能也很困难Stack

于 2013-04-18T16:59:09.577 回答
0

只是为了补充讨论,内部类将有权访问 Stack 类的私有数据,因此通过这种方式,Stack 类将设法处理客户端程序员一个对象或多个对象(迭代器和仍然这些对象将能够访问该类并提供对集合的单独迭代。

于 2014-03-31T21:10:30.807 回答