java Iterable接口和Iterator迭代器iterator
接口定义如下
public interface Iterator<E> { boolean hasNext(); E next(); void remove();}
该接口仅仅包含了三个函数,hasNext()和next()方法在我们常用的集合遍历中出现。 三个函数的作用:
使用next()获得序列中的下一个元素。使用hasNext()检查序列中是否还有元素。使用remove()将迭代器新返回的元素删除。
对于已经实现了iterator接口的集合,一般遍历集合的写法为 如,我们常用的list集合,list集合已经实现了iterator接口 – 方法一:for
list l = new ArrayList(); l.add("aa"); l.add("bb"); l.add("cc"); for (Iterator iter = l.iterator(); iter.hasNext();) { String str = (String)iter.next(); System.out.println(str); }
方法二 :while
Iterator iter = l.iterator(); while(iter.hasNext()){ String str = (String) iter.next(); System.out.println(str); }
这里我们查看 Abstractlist源码,中间有关于iterator实现细节,上面的iter实际上是多态,调用的其实是list的抽象Abstractlist类中的iterator方法:
private class Itr implements Iterator<E> { int cursor = 0; int lastRet = -1; int expectedModCount = modCount; public boolean hasNext() { return cursor != size(); } public E next() { checkForComodification(); try { int i = cursor; E next = get(i); lastRet = i; cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
通过源码,我们可以更加清晰的看出iterator三个函数的实现机制,细心的读者可能会发现,move()方法中 expectedModCount = modCount;有这样一个表达式。这其实是list中的快速失败机制。modcount在arraylist中的增删会使得其值变化,而expectedModcount是在遍历中维持的值,如果这两者不相等,表示在遍历的时候,出现了写操作。导致了数据不一致。 具体可以见博客[ConcurrentModificationException][1]
使用迭代器iterator的好处可以总结为如下: **
封装容器的内部实现细节,对于不同的集合,可以提供同一的遍历方式,简化客户端的访问和获取容器内数据。
**
Iterable
接口定义如下
public interface Iterable<T> { /** * Returns an iterator over a set of elements of type T. * * @return an Iterator. */ Iterator<T> iterator();}
Java SE5引入了Iterable接口,该接口包含一个能够产生Iterator的iterator()方法,并且Iterable接口被foreach用来在序列中移动。因此你创建了任何实现Iterable的自定义类,都可以将它用于foreach语句中。
Iterable的主要作用为:实现Iterable接口来实现适用于foreach遍历的自定义类。
来看一个简单的例子:
package com.andieguo.iterabledemo;import java.util.Iterator;public class IterablerClass<T> implements Iterable<T>{ private T[] array = null; public IterablerClass(T[] t){ this.array = t ; } @Override public Iterator<T> iterator() { // TODO Auto-generated method stub return new Iterator<T>() { private Integer index = 0; @Override public boolean hasNext() { // TODO Auto-generated method stub return index<array.length; } @Override public T next() { // TODO Auto-generated method stub return array[index++]; } @Override public void remove() { // TODO Auto-generated method stub } }; }public static void main(String[] args) {IterablerClass<String> iterablerClass = new IterablerClass<String>(new String[]{"hello","world","today","happy","sorrow"}); for(String s:iterablerClass){ System.out.print(s+" "); } }}
[1]http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html
一个人去旅行,而且是去故乡的山水间徜徉。