Java中Iterator的实现与C ++中的实现有何不同?
答案 0 :(得分:8)
在当前的C ++(98)标准库(特别是以前称为STL的部分)中定义了一种非常接近C指针(包括算术)的迭代器形式。因此他们只是指向某个地方。为了有用,您通常需要两个指针,以便您可以在它们之间进行迭代。我理解C ++ 0x引入的范围更像Java迭代器。
Java在1.2中引入了Iterator
(和ListIterator
)接口,主要取代了更详细的Enumerable。 Java没有指针算术,因此不需要像指针一样工作。他们有hasNext
方法来查看它们是否已经结束,而不是需要两个迭代器。缺点是它们不够灵活。系统需要方法为subList
,而不是在两个迭代器之间进行迭代,这是包含列表中的特定点。
风格的一般差异是,虽然C ++通过模板使用“静态多态”,但Java使用接口和常见的动态多态。
迭代器的概念是提供粘合剂以允许分离“算法”(真正的控制流)和数据容器。两种方法都做得相当好。在理想情况下,“普通”代码几乎不应该看到迭代器。
答案 1 :(得分:6)
C ++没有指定迭代器的实现方式。但它确实指定了它们的接口以及它们必须提供的最小行为才能使用其他标准库组件。
例如,对于输入迭代器,标准指定必须通过*运算符解除引用迭代器。但是,它没有说明如何实施该运营商。
答案 2 :(得分:2)
在C ++中,你会看到人们一直在传递迭代器。 C ++迭代器“指向”容器的特定元素。您可以取消引用迭代器来获取元素(并且您可以反复执行此操作)。您可以有效地擦除迭代器引用的元素。您还可以复制迭代器(通过分配给另一个变量,或者通过值将迭代器传递给函数)来同时跟踪多个位置。 C ++中的迭代器可能会因容器上的某些操作而“无效”,具体取决于容器。当迭代器变为无效(其规则可能很复杂)时,使用迭代器的操作具有未定义的行为,并且可能(不一致地)使程序崩溃或返回不正确的结果;虽然在某些数据结构中(例如std::list
),迭代器通过容器的大多数修改仍然有效。
在Java中,您没有看到这种用法。 Java中的迭代器指向“两个”元素之间,而不是“在”一个元素。使用迭代器获取元素的唯一方法是将其向前移动以获取移动的元素。当然,这会改变迭代器的状态,你不能回头;除非你有一个ListIterator
,在这种情况下你可以向前和向后移动(但是为了保持静止而必须向前和向后移动仍然很烦人)。您无法复制迭代器,因为该接口不公开公共复制方法;因此,例如,您不能只将特定位置的标记传递给函数,而不必为该函数提供对同一迭代器的引用,从而允许它们更改迭代器的状态。在Java中,迭代器将通过对容器的任何修改而无效(至少在标准容器中),除非通过迭代器自己的add()
或remove()
方法,这是过于保守的(例如,大多数修改LinkedList
不应该影响迭代器)。当您尝试使用无效的迭代器时,它会引发ConcurrentModificationException
(因为它与并发无关而引起混淆),而不是可能导致未定义的行为,这很好。
答案 3 :(得分:1)
C ++迭代器(STL)尝试通过运算符重载尽可能地模仿指针语法。
标准规范定义了各种迭代器概念(如前向,双向,随机访问,输入,输出)。每个概念应该与特定接口匹配(例如,用于转发迭代器的++运算符以按顺序转到下一个元素, - 用于双向,+,+ =用于随机访问等)。
答案 4 :(得分:0)
实现分别完全由C ++ / Java中的标准库供应商/ JRE供应商定义。只要他们的行为符合各自的标准,他们就可以自由地实施它们。