zoukankan      html  css  js  c++  java
  • 迭代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)咨询.

  • 相关阅读:
    《android深入探索》第七章心得
    《android深入探索》第六章心得
    《android深入探索》第五章心得
    《android深入探索》第四章心得
    《android深入探索》第三章心得
    《android深入探索》第二章心得
    嵌入式Linux的调试技术
    硬件抽象层:HAL
    让开发板发出声音:蜂鸣器驱动
    LED将为我闪烁:控制发光二极管
  • 原文地址:https://www.cnblogs.com/zouzz/p/6090105.html
Copyright © 2011-2022 走看看