迭代器:Java中的最后一个元素

时间:2017-06-20 09:07:41

标签: java iterator

就像在C ++中一样,我们有end(),其中迭代器最终位于最后一个元素之后的位置,对于Java迭代器是否合适呢?

0[array]

E.g。在C ++中,我们有:

while (iterator.hasNext()) {
    String color = iterator.next();
}

我如何在Java思维/术语中绘制上述插图?

4 个答案:

答案 0 :(得分:2)

这里有一个关键的区别:在C ++中,你仍然在谈论“内存位置”意义上的“指针”。

在C ++中,指向集合外部的“结束”是有意义的(在某种程度上;正如另一个答案很好地概述)。

在Java中,它没有。

因为“我们”不把集合视为“记忆中的一个连续的地方”。 “我们”将其视为......一系列物品。你可以迭代它们;这是所有你需要知道的。

答案 1 :(得分:2)

在Java中,如果它实现next()hasNext(),则它是迭代器。关于底层内存模型没有任何说法。 “过去的最后一个元素”并不是一个有用的概念。

您的C ++案例仅与某些容器密切相关,例如: std::vector。例如,std::list没有以你拥有它的方式建模。将“一个接一个结束”视为实际的记忆位置并不是一个好主意。这个概念已经悄悄进入C ++的说法,因为你被允许在数组的末尾或标量的地址之外设置一个指针。

答案 2 :(得分:2)

在Java中,Iterator接口,这意味着必须有一个实现接口方法的具体类。现在,这取决于使用的集合类型。例如,要迭代List类型的集合,我们使用ListIterator

对于listIterator,它没有当前元素。光标位置位于元素之间,集合的开头或列表中最后一个元素的末尾。插图应该更清楚。

因此,当hasNext()返回false时,您知道您位于Collection(List,在我们的例子中)的末尾,它会抛出 NoSuchElementException

Sample of a listIterator

答案 3 :(得分:0)

Java迭代器实现java.util.Iterator<E>接口。

当新创建迭代器时(逻辑上)在迭代元素的第一个元素之前。这是因为next()将返回第一个元素(如果有的话)。

当它用尽时,迭代器在(逻辑上)在最后一个元素之后,hasNext()将返回false

然而,Java通常不会为迭代器实现值比较语义。

考虑:

public static void main (String[] args) throws java.lang.Exception
{
    ArrayList<Integer> numbers=new ArrayList();
    numbers.add(7);
    numbers.add(8);

    Iterator<Integer> begin=numbers.iterator();
    Iterator<Integer> iter=numbers.iterator();

    System.out.println(begin.equals(iter));
} 

预期输出为false

没有什么可以反对实现equals()来实现Iterator实现class的自定义interface的值语义,但提供的EndIterator相当有限,而且#39}没有通用的方式将它放在顶部。

C ++迭代器只是迭代器的一个更丰富的协议。

我们当然可以实现一个equals()类(见下文),但除非有比较迭代器的有意义的方法(比如说end()),否则它不会有多大用处。

Iterator方法唯一有意义的事情是返回false始终返回hasNext()next()并始终在调用class EndIterator<E> implements Iterator<E> { public boolean hasNext(){ return false; } public E next(){ throw new NoSuchElementException(); } public int hashCode(){ return 123456;//Arbitrary and technically invalid... } public boolean Equals(Object other){ if(!(other instanceof Iterator)){ return false; } Iterator otheri=(Iterator)other; return otheri.hasNext()==false; } } 时抛出异常}。

end()

请注意,这并没有真正起作用,因为Java集合没有实现一个等式关系,即如果两个迭代器在同一个容器中的迭代点相同(例如),则它们是相等的。 C ++具有这一点,它使<Line x:Name="StartAngleLine" X1="{Binding Path=StartAngleX1}" X2="{Binding Path=StartAngleX2}" Y1="{Binding Path=StartAngleY1}" Y2="{Binding Path=StartAngleY2}" Stroke="Aqua" StrokeThickness="6"/> 有意义,但它不能(很容易)改装到Java上。