迭代器:Java中超过最后一个元素的元素 就像C++一样,我们有()迭代器在最后一个元素的位置结束,java迭代器真的是这样吗?< /P> while (iterator.hasNext()) { String color = iterator.next(); } 例如,在C++中,我们有: Blue Green Purple ^ ^ ^ ^ begin end 我如何在Java思想/术语中画出上面的插图?
这里有一个关键的区别:在C++中,你仍然在“内存位置”的意义上谈论“java”。p> 在C++中,指向集合外的“结束”是有意义的(在某种程度上,正如其他答案很好地勾勒出的)。 在Java中,它不是迭代器:Java中超过最后一个元素的元素 就像C++一样,我们有()迭代器在最后一个元素的位置结束,java迭代器真的是这样吗?< /P> while (iterator.hasNext()) { String color = iterator.next(); } 例如,在C++中,我们有: Blue Green Purple ^ ^ ^ ^ begin end 我如何在Java思想/术语中画出上面的插图?,java,iterator,Java,Iterator,这里有一个关键的区别:在C++中,你仍然在“内存位置”的意义上谈论“java”。p> 在C++中,指向集合外的“结束”是有意义的(在某种程度上,正如其他答案很好地勾勒出的)。 在Java中,它不是 因为“我们”不认为收藏是“记忆中一个连续的地方”。“我们”认为它是。。。对象的集合。你可以迭代它们;这就是你需要知道的一切 在Java中,如果某个东西实现了next()和hasNext(),那么它就是迭代器。关于底层的内存模型,我们什么也没说。“一过最后一个元素”不是一个有用的概念 您的C++案例只与
因为“我们”不认为收藏是“记忆中一个连续的地方”。“我们”认为它是。。。对象的集合。你可以迭代它们;这就是你需要知道的一切 在Java中,如果某个东西实现了
next()
和hasNext()
,那么它就是迭代器。关于底层的内存模型,我们什么也没说。“一过最后一个元素”不是一个有用的概念
您的C++案例只与某些容器相关,例如:代码> STD::vector < /代码>。例如,
std::list
不是按照您的方式建模的。此外,将“一个过了终点”视为实际的内存位置也不是一个好主意。这个概念已经进入C++语言,因为你可以在数组的末尾设置一个指针,或者一个标量的地址。< /P> < P> java迭代器实现了<代码> java。UTI.IATRATORION/COD>接口。
新创建的迭代器(逻辑上)位于迭代元素的第一个元素之前。这是因为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));
}
请注意,这实际上不起作用,因为Java集合没有实现一个相等关系,即如果两个迭代器(比如)在同一容器中的同一个迭代点上,那么它们是相等的。
C++有这样的功能,它使
ListIterator
对于列表迭代器
,它没有保存的当前元素。光标位置将位于元素之间,在集合的开头或列表中最后一个元素的末尾。插图应该使它更清楚
因此,当hasNext()
返回false时,您就知道自己在集合(在本例中为列表)的末尾,该集合抛出了一个NoTouchElementException
RTFM->
迭代器是一个接口。任何实现都必须提供next()
和hasNext()
。Java中的迭代器有点像指针,只是它不指向“当前”元素(就像C++中的*一样),而是指向下一个元素的前面。因此,C++和java模型之间有一个轻微的错配。@安第特纳:如果它指向当前元素之前,那么它不会移动到下一个调用下的最后一个元素吗?例如,^蓝色^绿色^紫色^
。仍然是一个有趣的问题。我总是喜欢质疑那些似乎是铁板一块的事情。我不太明白迭代器等式和任何事情有什么关系。是的,java集合在每次调用时都返回新的迭代器,而不是,数组列表迭代器的equal是引用比较,所以equals失败,但这不是预期的。而且我也不知道C++中的迭代器会更丰富些。问题是关于end()
方法的。但是,除非您可以与其他对象进行比较,否则这种方法是非常无用的,因为end()
需要是一个基本上死的对象。在提供的迭代器
接口
中,您无法真正处理end()
需要返回的内容。end()
就迭代器
而言是死对象,但在双向列表迭代器
@M.Prokhorov的情况下,它可以解除。但是在迭代器
接口的范围内,它是一个死对象。我的观点是,有些迭代器是“结束后”的,但这与“结束”的哨兵位置的概念不同,因为JavaIterator
和子接口没有实现equals()
来具有值语义。问题是比较C++和java。
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;
}
}