JAVA:Enumeration列舉遍歷和iterator遍歷的區別原始碼分析
阿新 • • 發佈:2018-12-07
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更方便