1. 程式人生 > >JAVA:Enumeration列舉遍歷和iterator遍歷的區別原始碼分析

JAVA:Enumeration列舉遍歷和iterator遍歷的區別原始碼分析

Enumeration與iterator都是提供對集合元素遍歷的介面。

Iterator提供的方法:

boolean hasNext():用來判斷當前遊標後面是否還存在元素,如果存在就返回true,不存在就返回false。

Object next():先返回當前遊標右邊的元素,然後遊標後移一個位置。

void remove():刪除最近返回的元素。

使用:

public static void main(String [] args){
        ArrayList<Integer> arrayList=new ArrayList<Integer>();
        arrayList.add(12);
        arrayList.add(15);
        arrayList.add(45);
        arrayList.add(16);
        Iterator<Integer> iterator = arrayList.iterator();
        while (iterator.hasNext()){
            Integer next=iterator.next();
            System.out.print(next+"  ");
        }
        System.out.println();
    }
}
結果:12  15  45  16  

原始碼:

   public Iterator<E> iterator() {
        return new 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;//版本號在次體現fail-fast

        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];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }


Enumeration中的兩個方法:

boolean hashMoreElements():判斷是否有更多的元素可以提取,如果有的話就返回true,否則返回false。

Object nextElement():如果至少存在一個可提供的元素,則返回此列舉的下一個元素。

使用:

public static void main(String [] args) {
        Hashtable<Integer, Integer> hashtable = new Hashtable<Integer, Integer>();
        hashtable.put(11, 12);
        hashtable.put(22, 15);
        hashtable.put(33, 45);
        hashtable.put(44, 16);
        Enumeration<Integer> elements = hashtable.elements();
        while (elements.hasMoreElements()) {
           Integer next= elements.nextElement();
           System.out.print(next+" ");
        }
        System.out.println();
}
結果:16 45 15 12

原始碼分析: 

   public Enumeration elements() {
        return new HashtableEnumerator(table, false);
    }//通過呼叫elements方法,建立 HashtableEnumerator例項物件, HashtableEnumerator實現了//Enumeration介面中的hasMoreElements(),nextElement()方法
 class HashtableEnumerator implements Enumeration {
        boolean keys;
        int index;
        HashtableEntry table[];
        HashtableEntry entry;

        HashtableEnumerator(HashtableEntry table[], boolean keys) {
            this.table = table;
            this.keys = keys;
            this.index = table.length;
        }
//獲取下一個元素:從hasMoreElements()和nextElement()可以看出hashtable的elements()遍歷方式
//首先從後向前遍歷table陣列,table陣列的每個節點都是一個單向連結串列(entry);然後在依次遍歷連結串列

        public boolean hasMoreElements() {
            if (entry != null) {
                return true;
            }
            while (index-- > 0) {
                if ((entry = table[index]) != null) {
                    return true;
                }
            }
            return false;
        }

        public Object nextElement() {
            if (entry == null) {
                while ((index-- > 0) && ((entry = table[index]) == null));
            }
            if (entry != null) {
                HashtableEntry e = entry;
                entry = e.next;
                return keys ? e.key : e.value;//元素返回是倒著輸出
            }
            return null;
        }
    }

}

總結Iterator和Enumeration的重要區別:
1:Enumeration中沒有刪除方法,只有遍歷。
2.Iterator支援fail-fast機制,而Enumeration不支援
Enumeration是JDK1.0新增的介面,使用到它的函式包括Vector和Hashtable等類,這些類都是JDK1.0中加入的,
Enumeration存在的目的就是為他們提供遍歷介面。Iterator是JDK1.2才新增的介面,它也是為HashMap,ArrayList
等集合提供遍歷介面。Iterator是支援fail-fast機制:當多個執行緒對同一個集合內容進行操作時,就可能會產生fail-fast事件。
一般情況下使用for迴圈遍歷集合,為什麼還需要迭代器或者列舉法遍歷集合?

對於含有索引的集合,可以使用for迴圈,通過下標遍歷,Arraylist(有index)和Linkedlist(有next),因此也可以用增強for迴圈和迭代器,而對於以hashmap,hashtable,hashtree等,因為沒有索引,不能使用for迴圈。用iterator更方便