Iterator、Iterable接口的使用及詳解


Java集合類庫將集合的接口與實現分離。同樣的接口,可以有不同的實現。

Java集合類的基本接口是Collection接口。而Collection接口必須繼承java.lang.Iterable接口。

以下圖表示集合框架的接口,java.lang以及java.util兩個包里的。其他部分可以從左向右看,比如Collection的Subinterfaces有List,Set以及Queue等。

package java.util;

/**
 * An iterator over a collection.  Iterator takes the place of Enumeration in
 * the Java collections framework.  Iterators differ from enumerations in two
 * ways: <ul>
 *    <li> Iterators allow the caller to remove elements from the
 *         underlying collection during the iteration with well-defined
 *          semantics.
 *    <li> Method names have been improved.
 * </ul><p>
 *
 * This interface is a member of the 
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
 * Java Collections Framework</a>.
 *
 * @author  Josh Bloch
 * @version %I%, %G%
 * @see Collection
 * @see ListIterator
 * @see Enumeration
 * @since 1.2
 */
public interface Iterator<E> {
    /**
     * Returns <tt>true</tt> if the iteration has more elements. (In other
     * words, returns <tt>true</tt> if <tt>next</tt> would return an element
     * rather than throwing an exception.)
     *
     * @return <tt>true</tt> if the iterator has more elements.
     */
    boolean hasNext();

    /**
     * Returns the next element (每一次迭代,the next element就是index為0的元素)in the iteration.
     *
     * @return the next element in the iteration.
     * @exception NoSuchElementException iteration has no more elements.
     */
    E next();

    /**
     * 
     * Removes from the underlying collection the last element returned by the
     * iterator (optional operation).  This method can be called only once per
     * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
     * the underlying collection is modified while the iteration is in
     * progress in any way other than by calling this method.
     *
     * @exception UnsupportedOperationException if the <tt>remove</tt>
     *          operation is not supported by this Iterator.
     
     * @exception IllegalStateException if the <tt>next</tt> method has not
     *          yet been called, or the <tt>remove</tt> method has already
     *          been called after the last call to the <tt>next</tt>
     *          method.
     */
    void remove();
}

以下例子是利用了Iterator接口的着三個方法,實現遍歷ArrayList<String>類型。
一開始迭代器在所有元素的左邊,調用next()之后,迭代器移到第一個和第二個元素之間,next()方法返回迭代器剛剛經過的元素
hasNext()若返回True,則表明接下來還有元素,迭代器不在尾部。
remove()方法必須和next方法一起使用,功能是去除剛剛next方法返回的元素

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class ForEachDemo {
    public static void main(String... arg) {
        Collection<String> a = new ArrayList<String>();
        a.add("Bob");
        a.add("Alice");
        a.add("Lisy");

        Iterator<String> iterator = a.iterator();
        while (iterator.hasNext()) {
            String ele = iterator.next();
            System.out.println(ele);//Bob  Alice  Lisy    
        }
        System.out.println(a);//[Bob, Alice, Lisy]  
        iterator = a.iterator();
        iterator.next();
        iterator.remove();
        System.out.println(a);//[Alice, Lisy]  
    }
}  
package java.lang;

import java.util.Iterator;

/** Implementing this interface allows an object to be the target of
 *  the "foreach" statement.
 * @since 1.5
 */
public interface Iterable<T> {

    /**
     * Returns an iterator over a set of elements of type T.
     * 
     * @return an Iterator.
     */
    Iterator<T> iterator();
}

for-each循環可以與任何實現了Iterable接口的對象一起工作。
而java.util.Collection接口繼承java.lang.Iterable,故標准類庫中的任何集合都可以使用for-each循環。

Collection接口

此接口的方法

public interface Collection<E>{......}

 
Modifier and Type Method and Description
boolean add(E e)
Ensures that this collection contains the specified element (optional operation).
boolean addAll(Collection<? extends E> c)
Adds all of the elements in the specified collection to this collection (optional operation).
void clear()
Removes all of the elements from this collection (optional operation).
boolean contains(Object o)
Returns  true if this collection contains the specified element.
boolean containsAll(Collection<?> c)
Returns  true if this collection contains all of the elements in the specified collection.
boolean equals(Object o)
Compares the specified object with this collection for equality.
int hashCode()
Returns the hash code value for this collection.
boolean isEmpty()
Returns  true if this collection contains no elements.
Iterator<E> iterator()
Returns an iterator over the elements in this collection.
boolean remove(Object o)
Removes a single instance of the specified element from this collection, if it is present (optional operation).
boolean removeAll(Collection<?> c)
Removes all of this collection's elements that are also contained in the specified collection (optional operation).
boolean retainAll(Collection<?> c)
Retains only the elements in this collection that are contained in the specified collection (optional operation).
int size()
Returns the number of elements in this collection.
Object[] toArray()
Returns an array containing all of the elements in this collection.
<T> T[] toArray(T[] a)
Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array.

因為其中有一個返回值為Iterator<E>類型的iterator()方法,所以,java.util.Collection接口必須繼承java.lang.Iterable接口

 

實現Collection接口的每一個類都要實現以上眾多方法,但開發者自己實現很麻煩。所以java提供了AbstractCollection類來編寫具體的類。

java.util
Interface Collection<E>

All Superinterfaces:
Iterable<E>
All Known Subinterfaces:
BeanContext, BeanContextServices, BlockingDeque<E>, BlockingQueue<E>, Deque<E>, List<E>, NavigableSet<E>, Queue<E>, Set<E>, SortedSet<E>
All Known Implementing Classes:
AbstractCollection, AbstractList, AbstractQueue, AbstractSequentialList, AbstractSet, ArrayBlockingQueue, ArrayDeque, ArrayList, AttributeList, BeanContextServicesSupport, BeanContextSupport, ConcurrentLinkedQueue, ConcurrentSkipListSet, CopyOnWriteArrayList, CopyOnWriteArraySet, DelayQueue, EnumSet, HashSet, JobStateReasons, LinkedBlockingDeque, LinkedBlockingQueue, LinkedHashSet, LinkedList, PriorityBlockingQueue, PriorityQueue, RoleList, RoleUnresolvedList, Stack, SynchronousQueue, TreeSet, Vector

Collection接口有三個常用的子接口,分別是List,Set,Queue。

http://blog.csdn.net/xujinsmile/article/details/8543544

為什么一定要去實現Iterable這個接口呢? 為什么不直接實現Iterator接口呢?

看一下JDK中的集合類,比如List一族或者Set一族,
都是繼承了Iterable接口,但並不直接繼承Iterator接口。
仔細想一下這么做是有道理的。因為Iterator接口的核心方法next()或者hasNext()
依賴於迭代器的當前迭代位置的。
如果Collection直接繼承Iterator接口,勢必導致集合對象中包含當前迭代位置的數據(指針)。
當集合在不同方法間被傳遞時,由於當前迭代位置不可預置,那么next()方法的結果會變成不可預知。
除非再為Iterator接口添加一個reset()方法,用來重置當前迭代位置。
但即時這樣,Collection也只能同時存在一個當前迭代位置。
而Iterable則不然,每次調用都會返回一個從頭開始計數的迭代器。
多個迭代器是互不干擾的。
http://www.cnblogs.com/highriver/archive/2011/07/27/2077913.html

import java.util.Iterator;

public class ForEachAPIDemo {
    public static void main(String[] args) throws Exception {
        Students students = new Students(10);
        for (Student student : students) {
            System.out.println(student.getSid() + ":" + student.getName());
        }
    }
}

// 支持for each迭代循環的學生集合類
class Students implements Iterable<Student> {
    // 存儲所有學生類的數組
    private Student[] students;

    // 該構造函數可以生成指定大小的學生類變量數組,並初始化該學生類變量數組
    public Students(int size) {
        students = new Student[size];
        for (int i = 0; i < size; i++) {
            students[i] = new Student(String.valueOf(i), "學生" + String.valueOf(i));
        }
    }

    @Override
    public Iterator<Student> iterator() {
        return new StudentIterator();
    }

    // 實現Iterator接口的私有內部類,外界無法直接訪問
    private class StudentIterator implements Iterator<Student> {
        // 當前迭代元素的下標
        private int index = 0;

        // 判斷是否還有下一個元素,如果迭代到最后一個元素就返回false
        public boolean hasNext() {
            return index != students.length;
        }

        @Override
        public Student next() {
            return students[index++];
        }

        // 這里不支持,拋出不支持操作異常
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

class Student {
    private String sid;
    private String name;

    public Student(String sid, String name) {
        setSid(sid);
        setName(name);
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sid='" + sid + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM