迭代保证具有以下方法:for-each循环如何知道从哪里开始?
- hasNext()
- 下()
- 删除(可选)
当for-each
循环迭代通过iterable
类对象,它如何知道对象开始与?上述方法提供了明确的路径,但是什么指向了起点?
For-each
保证迭代通过全部相关对象。根据类别及其实现,从何处开始可能至关重要(考虑forward linked list
或具有root
元素的任何其他实现)。
它是如何工作的?
如果我的问题没有意义,请解释原因。
迭代保证具有以下方法:for-each循环如何知道从哪里开始?
当for-each
循环迭代通过iterable
类对象,它如何知道对象开始与?上述方法提供了明确的路径,但是什么指向了起点?
For-each
保证迭代通过全部相关对象。根据类别及其实现,从何处开始可能至关重要(考虑forward linked list
或具有root
元素的任何其他实现)。
它是如何工作的?
如果我的问题没有意义,请解释原因。
什么正式名称叫增强for
声明(for(E e: Iterable<E> iterable)
)由编译器转换成如下代码相当于:
E e;
for(Iterator<E> it = iterable.iterator(); it.hasNext();) {
e = it.next();
// contents of your for loop
}
环路的行为是完全一样你写了一个明确的Iterator
,所以增强的for
循环的“起点”是无论如何都会启动iterable.iterator()
的任何地方。
foreach是循环从第一个到最后一个的简写。
定义“* first *”和“* last *”的定义类是不是从Java'Collection'派生的定义类? –
你可能想看看ArrayList
的执行Iterator
,Itr
内部类。
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
...
}
cursor
被默认初始化为0
。您使用cursor
来访问ArrayList
对象的后备数组中的元素(它是一个内部类,它可以访问该字段)。
类似的逻辑适用于Iterator
的其他实现。它总是依赖于底层的数据结构。作为另一个例子,Set
不应该有排序,但它确实实现了Iterator
。必须做出关于迭代器开始的地方的决定。
这一切都取决于你的收藏。
如果您的收藏是列表(通常为ArrayList
或LinkedList
),那么迭代器将根据它们的插入顺序进入列表顺序。
如果它是一个Map或Set,很难预测其成员的顺序。如果您使用的是Map或Set,实际上,您不应该依赖任何可预测的排序,因为它不符合这些集合的用途。但是,LinkedHashMap
或LinkedHashSet
可以用于如果您需要特定顺序但还需要Map或Set的功能。
如果我没有一个集合,但只是一个实现'Iterable'的类呢? –
它使用任何'next()'在第一次迭代时返回... –
您从容器获取的迭代器被初始化为开始。 – andy256
您可以在'Iterator'实现中定义从哪里开始。例如,对于'List',你有一个* straight *迭代器,它从第一个元素到最后一个元素,以及一个从最后一个元素到最后一个元素的反向迭代器。 –