迭代→遍歷:
- 一個標准化遍歷各類容器里面的所有對象的方法類(典型的設計模式)
- 把訪問邏輯從不同類型的集合類中抽象出來,從而避免向客戶端暴露集合的內部結構
迭代(Iterator)與枚舉(Enumeration)的區別:
- Iterator為一個接口,java.util.Iterator提供迭代的基本規則。Enumeration屬於Java Collections Framework ;
- 迭代器允許調用者在迭代期間從迭代器所指向的 collection 移除元素;
- 方法名稱得到了改進。
一、未使用Iterator
- 數組遍歷:
int[] arrays = new int[10]; for(int i = 0 ; i < arrays.length ; i++){ int a = arrays[i]; //do something }
上述實例缺點:
- 事先知道集合的內部結構,訪問代碼和集合本身是緊密耦合的,無法將訪問邏輯從集合類和客戶端代碼中分離出來。
- 每一種集合對應一種遍歷方法,客戶端代碼無法復用。
二、使用Iterator
- Iterator模式用同一種邏輯來遍歷集合,使得客戶端自身不需要來維護集合的內部結構,所有的內部狀態都由Iterator來維護。
- 客戶端從不直接和集合類打交道,它總是控制Iterator,向它發送"向前","向后","取當前元素"的命令,就可以間接遍歷整個集合。
1.使一個類可迭代的步驟:
Step1:在類聲明中加入implements Iterable<Item>,對應的接口為(即java.lang.Iterator)
public interface Iterable<Item>{
Iterator<Item> iterator(); }
Step2:在類中實現iterator()方法,返回一個自己定義的迭代器Iterator<Item>
public Iterator<Item> iterator(){ //如果需要逆序遍歷數組,自定義一個逆序迭代數組的迭代器 return new ReverseArrayIterator(); }
Step3:在類中設置內部類(如private class ReverseArrayIterator() ),內部類聲明中加入implements Iterator<Item>,對應的接口為(即java.util.Iterator)
public interface Iterator { boolean hasNext(); Object next(); void remove(); }
2.使用Iterator實例(摘自算法(第四版)):
下壓(LIFO)棧--能動態調整數組大小(學習迭代器只需要重點看后面兩大段):
import java.util.Iterator; import java.util.NoSuchElementException; public class ResizingArrayStack<Item> implements Iterable<Item> { private Item[] a; // array of items private int n; // number of elements on stack /** * Initializes an empty stack. */ public ResizingArrayStack() { a = (Item[]) new Object[2]; n = 0; } /** * Is this stack empty? * @return true if this stack is empty; false otherwise */ public boolean isEmpty() { return n == 0; } /** * Returns the number of items in the stack. * @return the number of items in the stack */ public int size() { return n; } // resize the underlying array holding the elements private void resize(int capacity) { assert capacity >= n; // textbook implementation Item[] temp = (Item[]) new Object[capacity]; for (int i = 0; i < n; i++) { temp[i] = a[i]; } a = temp; // alternative implementation // a = java.util.Arrays.copyOf(a, capacity); } /** * Adds the item to this stack. * @param item the item to add */ public void push(Item item) { if (n == a.length) resize(2*a.length); // double size of array if necessary a[n++] = item; // add item } /** * Removes and returns the item most recently added to this stack. * @return the item most recently added * @throws java.util.NoSuchElementException if this stack is empty */ public Item pop() { if (isEmpty()) throw new NoSuchElementException("Stack underflow"); Item item = a[n-1]; a[n-1] = null; // to avoid loitering n--; // shrink size of array if necessary if (n > 0 && n == a.length/4) resize(a.length/2); return item; } /** * Returns (but does not remove) the item most recently added to this stack. * @return the item most recently added to this stack * @throws java.util.NoSuchElementException if this stack is empty */ public Item peek() { if (isEmpty()) throw new NoSuchElementException("Stack underflow"); return a[n-1]; } /** * Returns an iterator to this stack that iterates through the items in LIFO order. * @return an iterator to this stack that iterates through the items in LIFO order. */ public Iterator<Item> iterator() { return new ReverseArrayIterator(); } // an iterator, doesn't implement remove() since it's optional private class ReverseArrayIterator implements Iterator<Item> { private int i; public ReverseArrayIterator() { i = n-1; } public boolean hasNext() { return i >= 0; } public void remove() { throw new UnsupportedOperationException(); } public Item next() { if (!hasNext()) throw new NoSuchElementException(); return a[i--]; } } }
遍歷時用foreach語句:
ResizingArrayStack<String> stack = new ResizingArrayStack<String>(); for (String str:stack ) { System.out.println(str); }
作者: 鄒珍珍(Pearl_zhen)
出處: http://www.cnblogs.com/zouzz/
聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出 原文鏈接 如有問題, 可郵件(zouzhenzhen@seu.edu.cn)咨詢.