迭代器模式---foreach的本质

        声明:文章内容根据大牛博客的内容,自己理解后,给自己做的学习笔记,文末会附上大牛博客地址链接。有需要沟通交流的可加我QQ群:425120333 
        在项目开发中经常会使用到各种各样的容器,内部实现分为三种情况,分别是数组(ArrayList)、链表(LinkedList)、散列(Set),使用了容器就需要知道每个容器中包含的内容,
    这时遍历整个容器就显得尤为重要。因为list是可以通过下标来访问的,存放的数据是有序的,这样的话通过序号遍历是能实现的,但是对set来说,是没法做到的,因为set是通过散列来存储数据的,
    没有下标的说法,这样一来就没法通过下标访问。
        下面参考jdk源码(主要是大牛的博客)自己分别实现ArrayList、LinkedList、Set三个类(简单实现)。
public class ArrayList<E> {
    private static final Integer originSize = 10;
    @SuppressWarnings("unchecked")
    E[] array = (E[]) new Object[originSize];
    private int size;

    public void add(E e) {
        if (size < originSize) {
            array[size++] = e;
        } else {
            @SuppressWarnings("unchecked")
            E[] copyArray = (E[]) new Object[10 + originSize];
            System.arraycopy(array, 0, copyArray, 0, size);
            copyArray[size++] = e;
            array = copyArray;
        }
    }

    public Object[] toArray() {
        @SuppressWarnings("unchecked")
        E[] copyArray = (E[]) new Object[size];
        System.arraycopy(array, 0, copyArray, 0, size);
        return copyArray;
    }

    public int size() {
        return size;
    }
}
public class LinkedList<E> {

    private Entry<E> header = new Entry<E>(null, null, null);
    private int size;

    public LinkedList() {
        header.next = header.previous = header;
    }

    public void add(E e) {
        Entry<E> newEntry = new Entry<E>(e, header, header.next);
        newEntry.previous.next = newEntry;
        newEntry.next.previous = newEntry;
        size++;
    }

    public Object[] toArray() {
        Object[] array = new Object[size];
        int i = size - 1;
        for (Entry<E> e = header.next; e != header; e = e.next) {
            array[i--] = e;
        }
        return array;
    }

    public int size() {
        return size;
    }

    private class Entry<E> {
        E value;
        Entry<E> previous;
        Entry<E> next;

        public Entry(E value, Entry<E> previous, Entry<E> next) {
            super();
            this.value = value;
            this.previous = previous;
            this.next = next;
        }
    }

}
import java.util.HashMap;
import java.util.Map;

public class Set<E> {
    private final static Object NULL = new Object();
    private Map<E, Object> map = new HashMap<E, Object>();

    public void add(E e) {
        map.put(e, NULL);
    }

    public int size() {
        return map.size();
    }

    public Object[] toArray() {
        return map.keySet().toArray();
    }
}
    因为着三个类都是自己编写的,没有实现迭代器接口,没法用foreach来迭代遍历,这里编写自己的迭代其实现类(基本和jdk源码类似,简化了一些)。
public interface Iterator<E> {
    public boolean hasNext();

    public E next();
}
public interface Iterable<E> {
    public Iterator<E> iterator();
}
    接下来要修改原先的ArrayList和LinkedList实现迭代器接口

实现了迭代器的ArrayList:

package com.cmcc.review;

public class ArrayList<E> implements Iterable<E> {
    private static final Integer originSize = 10;
    @SuppressWarnings("unchecked")
    E[] array = (E[]) new Object[originSize];
    private int size;

    public void add(E e) {
        if (size < originSize) {
            array[size++] = e;
        } else {
            @SuppressWarnings("unchecked")
            E[] copyArray = (E[]) new Object[10 + originSize];
            System.arraycopy(array, 0, copyArray, 0, size);
            copyArray[size++] = e;
            array = copyArray;
        }
    }

    public Object[] toArray() {
        @SuppressWarnings("unchecked")
        E[] copyArray = (E[]) new Object[size];
        System.arraycopy(array, 0, copyArray, 0, size);
        return copyArray;
    }

    public int size() {
        return size;
    }

    @Override
    public Iterator<E> iterator() {
        return new ListIterator();
    }

    private class ListIterator implements Iterator<E> {

        int index = 0;

        @Override
        public boolean hasNext() {
            if (index < size) {
                return true;
            }
            return false;
        }

        @Override
        public E next() {
            return array[index++];
        }

    }
}

实现了迭代器的LinkedList:

package com.cmcc.review;

public class LinkedList<E> implements Iterable<E> {

    private Entry<E> header = new Entry<E>(null, null, null);
    private int size;

    public LinkedList() {
        header.next = header.previous = header;
    }

    public void add(E e) {
        Entry<E> newEntry = new Entry<E>(e, header, header.next);
        newEntry.previous.next = newEntry;
        newEntry.next.previous = newEntry;
        size++;
    }

    public Object[] toArray() {
        Object[] array = new Object[size];
        int i = size - 1;
        for (Entry<E> e = header.next; e != header; e = e.next) {
            array[i--] = e;
        }
        return array;
    }

    public int size() {
        return size;
    }

    private class Entry<E> {
        E value;
        Entry<E> previous;
        Entry<E> next;

        public Entry(E value, Entry<E> previous, Entry<E> next) {
            super();
            this.value = value;
            this.previous = previous;
            this.next = next;
        }
    }

    @Override
    public Iterator<E> iterator() {
        // TODO Auto-generated method stub
        return new LinkedIterator();
    }

    private class LinkedIterator implements Iterator<E> {

        Entry<E> current = header;

        @Override
        public boolean hasNext() {
            if (current.previous != header) {
                return true;
            }
            return false;
        }

        @Override
        public E next() {
            E e = current.previous.value;
            current = current.previous;
            return e;
        }

    }

}

测试代码:

package com.cmcc.review;

public class TestClient {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("t1");
        list.add("t2");
        list.add("t3");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        LinkedList<String> list1 = new LinkedList<String>();
        list1.add("t11");
        list1.add("t12");
        list1.add("t13");
        Iterator<String> iterator1 = list1.iterator();
        while (iterator1.hasNext()) {
            System.out.println(iterator1.next());
        }
    }

}

控制台展示:
t1
t2
t3
t11
t12
t13
从结果中可以看出已经实现了遍历的效果。迭代器模式是一个已经没落的模式,很少会有人去专门写一个迭代器,因为迭代器是未容器服务的,为解决遍历这些容器中的元素而诞生的,
而现有使用的容器类都已经是实现了迭代器方法。作为一名java开发人员,尽量不要自己写迭代器模式,使用java提供的Iteraor一般就能满足要求了(特殊情况除外)。
参考大牛博客:http://www.cnblogs.com/zuoxiaolong/p/pattern18.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值