迭代Iterator的用法


迭代遍歷:

  • 一個標准化遍歷各類容器里面的所有對象的方法類(典型的設計模式)
  • 把訪問邏輯從不同類型的集合類中抽象出來,從而避免向客戶端暴露集合的內部結構 

迭代(Iterator)與枚舉(Enumeration)的區別:

  1.  Iterator為一個接口,java.util.Iterator提供迭代的基本規則。Enumeration屬於Java Collections Framework  ;
  2.  迭代器允許調用者在迭代期間從迭代器所指向的 collection 移除元素;
  3.  方法名稱得到了改進。

一、未使用Iterator

  •  數組遍歷:
int[] arrays = new int[10];  
for(int i = 0 ; i < arrays.length ; i++){  
       int a = arrays[i];  
       //do something  
   } 

    上述實例缺點:

  1. 事先知道集合的內部結構,訪問代碼和集合本身是緊密耦合的,無法將訪問邏輯從集合類和客戶端代碼中分離出來。
  2. 每一種集合對應一種遍歷方法,客戶端代碼無法復用

二、使用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)咨詢.


免責聲明!

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



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