码迷,mamicode.com
首页 > 其他好文 > 详细

迭代器模式

时间:2020-05-31 12:46:24      阅读:48      评论:0      收藏:0      [点我收藏+]

标签:nts   throw   代码实现   mic   return   职责   bsp   分离   下标   

迭代器模式简述

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。java api的Collection,Mapt等集合元素的遍历是用迭代器模式实现,将集合元素的遍历与具体的集合类分离,遵循单一职责原则。

迭代模式结构

以java api的Collection集合为例,模拟一下ArrayList跟LinkedList的迭代器的实现,具体迭代器模式主要结构如下:
1.Iterator(抽象迭代器):迭代器定义访问和遍历元素的接口,在这个例子指的是Iterator,定义二个抽象方法hasNext判断集合是否有下一个元素,next方法获取集合的当前元素。
2.ConcreteIterator (具体迭代器):具体迭代器实现迭代器接口,在这个例子值的是ArrayListIterator跟LinkedListIterator这二个具体迭代器,重写next,hasNext方法,不同的集合有不同的现实。
3.Aggregate (抽象聚合):聚合定义创建相应迭代器对象的接口或者(抽象类),java的Collection这个抽象类实现了Iterable接口(有个iterate方法),在本例简单定义一个MyCollection接口,定义了一个抽象iterate方法获取相应的迭代器。
4.ConcreteAggregate (具体聚合):具体聚合实现创建相应迭代器的接口(抽象类),该操作返回具体迭代器的一个适当的实例。在本例中指的是MyArrayList,MyLinkedList。重写了iterate方法获取相应的具体迭代器
 
uml图如下:
技术图片

 

 具体代码实现如下:

/**
 * 定义抽象集合类(集聚类)
 * 
 */
public interface MyCollection<E> {
    //提供一个方法产生迭代器
    Iterator<E> iterate ();

}

/**
 * 抽象迭代类
 */
public interface Iterator<E> {
    boolean hasNext();
    E next();
}

/**
 * 简单模拟一下ArrayList,简单写一个get add 方法 具体聚集类
 * @param <E>泛型E
 */
public class MyArrayList<E> implements MyCollection<E> {
    int size;
    Object [] elements;
    int capacity;

    public MyArrayList(int capacity) {
        if(capacity<0){
            throw new RuntimeException("ArrayList的容量必须大于0");
        } else if(capacity==0){
            elements=new Object[]{};
        } else{
            this.capacity = capacity;
            elements=new Object[10];
        }

    }

    public MyArrayList() {
        this(10);
    }
    //add方法
    public boolean add(E e){
        if(size>=capacity){
            int newCapacity=capacity+capacity>>1;
            Arrays.copyOf(elements,newCapacity);
        }
        elements[size++]=e;
        return true;
    }
    //get方法
    public E get(int index){
        if(index>size||index<0){
            throw new RuntimeException("数组下标越界");
        }
        return (E) elements[index];
    }
    //size方法
    public int size(){
        return size;
    }
    @Override
    public Iterator<E> iterate() {
        return new MyArrayListIterator();
    }
    //具体迭代器类
    private class MyArrayListIterator<E> implements Iterator<E> {
        int cursor=0;
        @Override
        public boolean hasNext() {
            if(cursor<size){
                return true;
            }
            return false;
        }

        @Override
        public E next() {
            E e= (E) elements[cursor];
            cursor++;
            return e;

        }
    }
}


/**
 * 为了模拟迭代器模式,自定义LInkedList的add方法,add方法
 */
public class MyLinkedList<E> implements MyCollection<E> {
    private Node<E> first;
    private Node<E> last ;
    int size;

    //add方法
    public boolean add(E e){
        Node<E> n =last;
        Node<E> newNode=new Node<E>(last,null,e);
        last=newNode;
        if(first==null){
            first=newNode;
        }else{
            n.next=newNode;
        }
        size++;
        return true;
    }
    //size方法
    public int size(){
        return size;
    }
    //get方法
    public E get(int index){
       return getNode(index).value;
    }
    //通过下标获取相关的Node节点
    Node<E> getNode(int index){
        if(index>size||index<0){
            throw new RuntimeException("LinkedList下标越界了");
        }
        if(index<(size>>1)){
            Node<E> n= first;
            for(int i=0;i<index;i++){
                n=n.next;
            }
            return n;
        } else{
            Node<E> n= last;
            for (int j=size;j>index;j--){
                n=n.pre;
            }
            return n;
        }

    }
    public MyLinkedList() {

    }

    @Override
    public Iterator<E> iterate() {
        return new LinkedListIterator<>(0);
    }
    private static class Node<E> {
        Node pre;
        Node next;
        E value;

        public Node(Node pre, Node next, E value) {
            this.pre = pre;
            this.next = next;
            this.value = value;
        }
    }
    
/**
*具体聚集类LinkedListIterator
*/
    private class LinkedListIterator<E> implements Iterator<E>{
        public LinkedListIterator(int cursor) {
            this.cursor = cursor;
            currentNode= (Node<E>) getNode(cursor);
        }

        private int cursor;
        Node<E> currentNode;
        @Override
        public boolean hasNext() {
            if(cursor<size){
                return true;
            }
            return false;
        }

        @Override
        public E next() {
            E e =currentNode.value;
            currentNode=currentNode.next;
            cursor++;
            return e;
        }
    }
}

/**
 * 迭代器客户端测试类,迭代器模式,主要用来变量自己的写聚集类(集合类)的元素
 */
public class IteratorClient {
    public static void main(String[] args) {
        MyArrayList<String> myArrayList =new MyArrayList<String>();
        {
            myArrayList.add("jack");
            myArrayList.add("mary");
            myArrayList.add("jerk");

        }
        //获取迭代器
        Iterator<String> iterator =myArrayList.iterate();
        //迭代器集合MyArrayList集合元素
        while(iterator.hasNext()){
            String name=iterator.next();
            System.out.println(name);
        }
        MyLinkedList<String> myLinkedList =new MyLinkedList<String>();
        {
            myLinkedList.add("jack");
            myLinkedList.add(null);
            myLinkedList.add("mary");

        }
        //LinkedList获取迭代器
        Iterator<String> iterator1 =myLinkedList.iterate();
        //迭代器遍历MyLinkedList集合元素
        while(iterator1.hasNext()){
            String name=iterator1.next();
            System.out.println(name);
        }

    }
}

迭代器模式总结

迭代器模式主要用来遍历自己定义的聚集类(逻辑型数据结构的类)的元素,第三方访问聚集类的元素,不需要关注访问聚集类的内部实现,只要通过访问迭代器接口实现类来实现聚集类元素的访问。

 
 
 
 
 
 
 
 
 

迭代器模式

标签:nts   throw   代码实现   mic   return   职责   bsp   分离   下标   

原文地址:https://www.cnblogs.com/shareAndStudy/p/12996981.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!