就像在C ++中一样,我们有end(),其中迭代器最终位于最后一个元素之后的位置,对于Java迭代器是否合适呢?
0[array]
E.g。在C ++中,我们有:
while (iterator.hasNext()) {
String color = iterator.next();
}
我如何在Java思维/术语中绘制上述插图?
答案 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
。
答案 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上。