【问题标题】:What is the difference between iterators in Java and C++?Java 和 C++ 中的迭代器有什么区别?
【发布时间】:2010-10-27 08:09:28
【问题描述】:

Iterator 在 Java 中的实现与在 C++ 中的实现有何不同?

【问题讨论】:

标签: java c++ iterator


【解决方案1】:

在当前的 C++ (98) 标准库(特别是以前称为 STL 的部分)中定义了一种非常接近 C 指针(包括算术)的迭代器。因此,他们只是指向某个地方。为了有用,您通常需要两个指针,以便您可以在它们之间进行迭代。我知道 C++0x 引入了更像 Java 迭代器的范围。

Java 在 1.2 中引入了Iterator(和ListIterator)接口,很大程度上取代了更冗长的 Enumerable。 Java 没有指针算法,所以没有必要表现得像一个指针。他们有一个hasNext 方法来查看他们是否已经走到最后,而不是需要两个迭代器。缺点是它们不太灵活。系统要求方法为subList,而不是在两个迭代器之间迭代是包含列表中的特定点。

风格上的一个普遍区别是,C++ 通过模板使用“静态多态”,而 Java 使用接口和常见的动态多态。

迭代器的概念是提供粘合剂以允许分离“算法”(真正的控制流)和数据容器。这两种方法都做得相当好。在理想情况下,“正常”代码应该几乎看不到迭代器。

【讨论】:

  • 我不认为这个问题会有很好的答案,但这是一个。 +1
  • 没有“C++ (97) 标准库”之类的东西。 ISO 14882 中描述的 C++ 标准出现于 1998 年,并于 2003 年更新。它没有定义迭代器的实现方式,但当然指定了它们提供的接口。
  • 它精确地定义了迭代器的概念是如何实现的。这似乎是问题所在。
  • 但是,如果我的英语还没有完全丢失,实现一个概念就意味着实现它。 C++ 标准没有规定如何实现迭代器。使用 C++1x 的 conceot 地图会更加宽松。您将能够编写代码,以便将普通整数用作输入迭代器,因为可以有概念图来教编译器如何取消引用整数。 C++ 精确地定义了这个概念。但它并没有准确定义应该如何实施该概念。这就是泛型编程的优势。
  • 但是我确实明白你的意思。 OP 确实以我和@neil 不熟悉的方式使用了“实现”,您决定采用与 OP 相同的方式。所以就我的观点而言,我同意你们两个。
【解决方案2】:

实现完全由标准库供应商/JRE 供应商分别在 C++/Java 中定义。只要他们的行为符合各自的标准,他们就可以随意实现它们。

【讨论】:

  • 这确实是实施这个词的不同应用。
【解决方案3】:

在 C++ 中,您会看到人们一直在传递迭代器。 C++ 迭代器“指向”容器的特定元素。您可以取消引用迭代器来获取元素(您可以一遍又一遍地这样做)。您可以有效地擦除迭代器引用的元素。您还可以复制迭代器(通过分配给另一个变量,或将迭代器按值传递给函数)以同时跟踪多个位置。 C++ 中的迭代器可能会因容器上的某些操作而“无效”,具体取决于容器。当迭代器失效(其规则可能很复杂)时,使用迭代器的操作具有未定义的行为,并且可能(不一致地)使您的程序崩溃或返回不正确的结果;尽管在某些数据结构中(例如std::list),迭代器在容器的大多数修改中仍然有效。

在 Java 中,您看不到这种用法。 Java 中的迭代器指向两个元素“之间”,而不是“在”一个元素。使用迭代器获取元素的唯一方法是将其向前移动以获取移动过的元素。当然,这会改变迭代器的状态,并且您无法返回;除非你有ListIterator,在这种情况下你可以向前和向后移动(但为了保持静止而必须向前和向后移动仍然很烦人)。您不能复制迭代器,因为接口没有公开公共复制方法;因此,例如,您不能只将特定位置的标记传递给函数,而不向该函数提供对您拥有的相同迭代器的引用,从而允许它们更改迭代器的状态。在 Java 中,除了通过迭代器自己的 add()remove() 方法之外,对容器的任何修改都会使迭代器失效(至少在标准容器中),这过于保守(例如,对 LinkedList 的大多数修改应该不影响迭代器)。当您尝试使用无效的迭代器时,它会引发 ConcurrentModificationException(之所以命名混淆,是因为它与并发无关)而不是可能导致未定义的行为,这很好。

【讨论】:

    【解决方案4】:

    C++ 没有指定迭代器是如何实现的。然而,它确实指定了它们的接口和它们必须提供的最小行为,以便与其他标准库组件一起工作。

    例如,对于输入迭代器,标准规定迭代器必须可以通过 * 运算符取消引用。但是,它没有指定如何实现该运算符。

    【讨论】:

    • Java 也没有指定; Iterator 是一个接口。我认为除此之外没有任何真正的方法可以回答这个问题。
    • C++ 库(以前称为 STL 的部分)非常精确地定义了迭代器概念的实现方式。
    • @Tom - C++ 语言由 ISO 标准指定,我可以向您保证,该文档中提到了应该如何实现迭代器。或者您可能在某种特殊意义上使用“实施”这个词?
    • 我在字典意义上使用“实施”这个词,因为它似乎是提问者正在做的。您的答案似乎是在吠叫代码猴子树。
    • 在 Java 和 C++ 等 OO 语言中通常会区分接口和实现。当提问者使用后一个术语时,我认为这就是他要问的。
    【解决方案5】:

    C++ 迭代器 (STL) 尝试通过运算符重载尽可能多地模仿指针语法。

    标准规范定义了各种迭代器概念(如前向、双向、随机访问、输入、输出)。每个概念都应该匹配一个特定的接口(例如,用于前向迭代器的 ++ 运算符以按顺序转到下一个元素,-- 用于双向,+、+= 用于随机访问等)。

    【讨论】:

      猜你喜欢
      • 2014-12-05
      • 2010-11-04
      • 2012-06-14
      • 2011-07-17
      • 2019-10-25
      • 1970-01-01
      • 2020-04-14
      • 2012-02-10
      • 2020-11-01
      相关资源
      最近更新 更多