【问题标题】:How does iterable work?可迭代如何工作?
【发布时间】:2014-11-26 15:51:36
【问题描述】:

大家好,我一直在自学 Java,并且正在完成这项任务。 http://ljing.org/games/focus/

所以我从头开始编写一个链表,我使用 LinkedList 类编写了一个 Deque 类 但是!

只有一个关于迭代器类的问题我不明白。 我只是不明白 Class Deque Iterator 应该做什么。

另外,我的代码中有这个:

class Deque<Item> implements Iterable<Item>.

然后编译器抱怨说在我的 Deque 类中我需要重写一个方法

@Override
public Iterator<Item> iterator()
{
    throw new UnsupportedOperationException("Not supported yet.");
}

但我不明白为什么

【问题讨论】:

  • 当您implements 一个接口时,您必须实现它的方法。你能澄清你在这方面的疑问吗? iteratior() 每次调用时都应该返回一个新的迭代器。
  • 你必须创建一个实现Iterator&lt;Item&gt;的实例并在iterator()方法中返回它。
  • 一个接口是一个contract,它指定了一些方法和它们的行为。为了实现一个接口,你的类必须绑定到那个契约,并提供那些应该按预期工作的方法。
  • 那么创建 Deque Iteraror 类的意义何在?是因为我会在 iterator() 方法中创建它的一个实例吗?

标签: java data-structures linked-list iterator deque


【解决方案1】:

在 Java 中有两个不同的接口用于迭代很重要,IterableIterator。它们各有不同的用途。

可迭代

当某个东西实现了这个接口时,这意味着它可以被迭代。这对我们很有用,因为 Java 为我们提供了一种使用 for-each 循环迭代实现 Iterable 的东西的快捷方式:

List<String> elements = ... ; // List is an instance of Iterable
for (String element : elements)
    System.out.println(element);

Iterable 的任何实例都可以在 for-each 循环中使用。如果您有自己的自定义 MyDeque 类来实现 Iterable,那么您也可以在 for-each 中使用它:

MyDeque<String> elements = ... ;
for (String element : elements)
    System.out.println(element);

这让我们...

迭代器

这个接口是实际执行迭代的方式。 for-each 循环编译成这样:

MyDeque<String> elements = ... ;
for (Iterator<String> $iter = elements.iterator(); $iter.hasNext();) {
    String element = $iter.next();
    System.out.println(element);
}

这段代码在功能上等同于上面的 for-each。 hasNext() 是延续条件(我还有更多东西要给你吗?),next() 实际上给你下一个元素,或者如果我们没有其他元素,则抛出 NoSuchElementException

使您的自定义双端队列实现Iterable 的目的只是为了让您可以使用类似for 循环的方式迭代双端队列中的元素。它的Iterator 实现可以让你真正那个迭代。

【讨论】:

    【解决方案2】:

    迭代器是用于访问集合中元素的概念。因为你说implements Iterable&lt;Item&gt;,你告诉编译器你提供了这种访问你的双端队列元素的机制。但这还不够。除了声称你会这样做,你实际上必须这样做。在这种情况下,做它就是实现方法。

    如果你不这样做会发生什么:

    因为你告诉编译器你会提供这个,所以你必须实现方法iterator(),这是这个访问概念的一部分。如果你不实现该方法,编译器会抱怨并告诉你“嘿,你说过你会这样做。所以信守诺言!”。

    有两种方法可以解决这个问题:

    1.) 首先,不要说你会通过迭代器提供访问概念 - 删除 implements Iterable&lt;Item&gt;

    2.) 信守诺言并实施方法。您将不得不为此编写一个自己的 Iterator 类。一旦您知道该做什么,这是一个相当短的任务。

    【讨论】:

    • 所以创建 Deque Iteraror 类的重点是因为我将在 iterator() 方法中创建它的一个实例?
    • 是的。但是 Deque 类并不是最终目的。目的是稍后当您在其他代码中使用您的 Deque 类时,您可以使用迭代器概念来访问 Deque 中的元素。这使得编写使用 Deque 类的代码变得更简单。就像将代码复杂性从一个代码部分移动到另一个代码部分,或者更好地说,从一个抽象级别到另一个抽象级别。使用带有迭代器的集合类查找示例代码,您会更好地理解它,例如前两个javapapers.com/core-java/java-iterator
    • 明白了,谢谢老兄。如果您有任何示例,可以链接我吗?再次感谢
    猜你喜欢
    • 2014-01-20
    • 2014-02-26
    • 2012-08-28
    • 2010-11-20
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多