Java 迭代器模式

来源:互联网 发布:朝鲜官二代 知乎 编辑:程序博客网 时间:2024/06/14 19:40

迭代器模式:提供一种方法顺序访问一个集合对象中的各个元素,而又不暴露其内部的表示。
类图
这里写图片描述

Aggregate:聚合,就是各种容器,提供抽象的返回迭代器的createIterator( )方法。
ConcreteAggregate:具体的容器类,像Java中的常用的ArrayList,HashMap等等要具体实现createIterator( )方法。
Iterator:所有迭代器必须实现的接口。利用其内部提供的方法来遍历集合元素。
ConcreteIterator:具体的迭代器实现。像ArrayList返回的迭代器,和HashMap的keySet()方法返回的迭代器。

看一下ArrayList返回的迭代器
在Java中,可以通过迭代器来遍历ArrayList。(通常还是直接for循环了)。

 ArrayList<String> list = new ArrayList<>(); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) {       System.out.println(iterator.next()); }

在Java中,可以通过迭代器来遍历HashMap。

        HashMap<String, String> hashMap = new HashMap<>();        Iterator<String> iterator1 = hashMap.keySet().iterator();        while (iterator1.hasNext()) {            String key = iterator1.next();            System.out.println("key:" + key + ",value:" + hashMap.get(key));        }

在Java中,集合都继承自Collection,而Collection继承了Iterable接口,在Iterable接口中定义了iterator()方法。

public interface Iterable<T> {    Iterator<T> iterator();}

iterator()方法返回的是一个Iterator。

public interface Iterator<E> {    boolean hasNext();    E next();    default void remove() {        throw new UnsupportedOperationException("remove");    }  //...省略其他方法

而不同的具体集合对Iterator<E>接口拥有不同的实现。

ArrayList的实现。

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;        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();            }        }        final void checkForComodification() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();        }    }

HashMap是利用Set进行遍历的。

public Set<K> keySet() {        Set<K> ks;        return (ks = keySet) == null ? (keySet = new KeySet()) : ks;    }//KetSet类final class KeySet extends AbstractSet<K> {        public final Iterator<K> iterator(){                 return new KeyIterator();         }//省略其他方法    }//KeyIterator 类 final class KeyIterator extends HashIterator        implements Iterator<K> {        public final K next() { return nextNode().key; }    }//HashIterator 类 abstract class HashIterator {        Node<K,V> next;        // next entry to return        Node<K,V> current;     // current entry        int expectedModCount;  // for fast-fail        int index;             // current slot        HashIterator() {            expectedModCount = modCount;            Node<K,V>[] t = table;            current = next = null;            index = 0;            if (t != null && size > 0) { // advance to first entry                do {} while (index < t.length && (next = t[index++]) == null);            }        }        public final boolean hasNext() {            return next != null;        }        final Node<K,V> nextNode() {            Node<K,V>[] t;            Node<K,V> e = next;            if (modCount != expectedModCount)                throw new ConcurrentModificationException();            if (e == null)                throw new NoSuchElementException();            if ((next = (current = e).next) == null && (t = table) != null) {                do {} while (index < t.length && (next = t[index++]) == null);            }            return e;        }        public final void remove() {            Node<K,V> p = current;            if (p == null)                throw new IllegalStateException();            if (modCount != expectedModCount)                throw new ConcurrentModificationException();            current = null;            K key = p.key;            removeNode(hash(key), key, null, false, false);            expectedModCount = modCount;        }    }

上面的代码展示了,ArrayList和HashMap内部是如何实现各自具体的迭代器的,但是我们在使用迭代器的时候,完全不用管它们内部的细节是如何实现的。我们所需要知道的所有一切就是,可以通过迭代器遍历集合就可以了。

最后再来看看迭代器模式的定义,是不是清晰很多了呢?

迭代器模式:提供一种方法顺序访问一个集合对象中的各个元素,而又不暴露其内部的表示。

结尾:参考
【1】Head First 设计模式。