zoukankan      html  css  js  c++  java
  • java设计模式-Iterator

    Iterator模式
    主要是用在容器的遍历上,其他的地方都不怎么用;理解一下,会用了就可以了;
     

    1、背景                    

    请动手自己写一个可以动态添加对象的容器;
    代码:
    ArrayList.java(是自己实现的,不是JDK)
    package com.cy.dp.iterator;
    
    public class ArrayList {
        Object[] objects = new Object[10];
        int index = 0;                                        //objects下一个空的位置
        
        /**
         * 如果数组容量已满,这里简单处理,扩容为原来的两倍;
         * sun的做法是有一个加权值,根据原来的容量,加上多少...
         * @param o
         */
        public void add(Object o){
            if(index == objects.length){
                Object[] newObjects = new Object[objects.length * 2];    
                System.arraycopy(objects, 0, newObjects, 0, objects.length);
                objects = newObjects;
            }
            
            objects[index] = o;
            index++;
        }
        
        public int size(){
            return index;
        }
        
    }

    Cat.java  辅助类:

    package com.cy.dp.iterator;
    
    public class Cat {
        private int id;
    
        public Cat(int id) {
            super();
            this.id = id;
        }
    }
    View Code

    Test.java 测试类:

    package com.cy.dp.iterator;
    
    import com.cy.dp.iterator.ArrayList;
    
    public class Test {
        public static void main(String[] args) {
            ArrayList al = new ArrayList();
            for(int i=0; i<15; i++){
                al.add(new Cat(i));
            }
            System.out.println(al.size());
        
            
        }
    }
    View Code

    2.上面容器的底层实现是用数组,下面使用链表来做个容器;

    简单解释链表:
    每一个链表里面装的都是一个一个的节点,每个节点里面包括两部分内容:1.数据本身 2.指向下一个节点的一个引用;
     
    代码:
    Node.java:
    package com.cy.dp.iterator;
    
    public class Node {
        private Object data;
        private Node next;
    
        public Node(Object data, Node next) {
            super();
            this.data = data;
            this.next = next;
        }
        
        public Object getData() {
            return data;
        }
        public void setData(Object data) {
            this.data = data;
        }
        public Node getNext() {
            return next;
        }
        public void setNext(Node next) {
            this.next = next;
        }
    }
    LinkedList.java:
    package com.cy.dp.iterator;
    
    public class LinkedList {
        Node head = null;
        Node tail = null;        //最末尾的节点
        int size = 0;            //记录当前链表里面Node个数
        
        public void add(Object o){
            Node n = new Node(o, null);
            if(head==null){
                head = n;
                tail = n;
            }
            tail.setNext(n);
            tail = n;
            size++;
        }
    
        public int size(){
            return size;
        }
    }

    Test.java 测试类:

    package com.cy.dp.iterator;
    
    import com.cy.dp.iterator.ArrayList;
    import com.cy.dp.iterator.LinkedList;
    
    public class Test {
        public static void main(String[] args) {
            //ArrayList al = new ArrayList();
            LinkedList al = new LinkedList();
            
            for(int i=0; i<15; i++){
                al.add(new Cat(i));
            }
            System.out.println(al.size());
        }
    }
    View Code

    3.考虑容器的可替换性        

    Test类中的容器类可以替换,但是测试方法无须修改;比如LinkedList里面添加元素方法为addObject()的话,那么代码就要重新修改了;
    所以有必要对ArrayList和LinkedList对外公开的方法统一起来;
    使用接口Collection,面向接口编程;好处是灵活,可扩展;
     
    于是就变成了代码:
    Collection.java:
    package com.cy.dp.iterator;
    
    public interface Collection {
        void add(Object o);
        int size();
    }

    ArrayList.java (实现Collection接口)

    package com.cy.dp.iterator;
    
    import com.cy.dp.iterator.Collection;
    
    public class ArrayList implements Collection {
        Object[] objects = new Object[10];
        int index = 0;                                        //objects下一个空的位置
        
        /**
         * 如果数组容量已满,这里简单处理,扩容为原来的两倍;
         * sun的做法是有一个加权值,根据原来的容量,加上多少...
         * @param o
         */
        public void add(Object o){
            if(index == objects.length){
                Object[] newObjects = new Object[objects.length * 2];    
                System.arraycopy(objects, 0, newObjects, 0, objects.length);
                objects = newObjects;
            }
            
            objects[index] = o;
            index++;
        }
        
        public int size(){
            return index;
        }
        
    }
    View Code

    LinkedList.java(实现Collection接口)

    package com.cy.dp.iterator;
    
    import com.cy.dp.iterator.Collection;
    
    public class LinkedList implements Collection {
        Node head = null;
        Node tail = null;        //最末尾的节点
        int size = 0;            //记录当前链表里面Node个数
        
        public void add(Object o){
            Node n = new Node(o, null);
            if(head==null){
                head = n;
                tail = n;
            }
            tail.setNext(n);
            tail = n;
            size++;
        }
    
        public int size(){
            return size;
        }
    }
    View Code

    Test.java测试类:

    public class Test {
        public static void main(String[] args) {
            Collection c = new LinkedList();
            
            for(int i=0; i<15; i++){
                c.add(new Cat(i));
            }
            System.out.println(c.size());
        }
    }
    View Code

    4.容器的遍历                

    因为上面ArrayList的遍历方式和LinkedList的遍历方式不同,遍历方式不统一的话,实现方式一变,代码就得跟着变;
    每一种容器都有自己的遍历方式,那么能不能找到一种统一的遍历方式呢?
     
    代码:
    Iterator接口:
    package com.cy.dp.iterator;
    
    public interface Iterator {
        Object next();
        boolean hasNext();
    }

    Collection接口:

    package com.cy.dp.iterator;
    
    public interface Collection {
        void add(Object o);
        int size();
        Iterator iterator();
    }

    ArrayList.java:

    package com.cy.dp.iterator;
    
    import com.cy.dp.iterator.Collection;
    
    public class ArrayList implements Collection {
        Object[] objects = new Object[10];
        int index = 0;                                        //objects下一个空的位置
        
        /**
         * 如果数组容量已满,这里简单处理,扩容为原来的两倍;
         * sun的做法是有一个加权值,根据原来的容量,加上多少...
         * @param o
         */
        @Override
        public void add(Object o){
            if(index == objects.length){
                Object[] newObjects = new Object[objects.length * 2];    
                System.arraycopy(objects, 0, newObjects, 0, objects.length);
                objects = newObjects;
            }
            
            objects[index] = o;
            index++;
        }
        
        @Override
        public int size(){
            return index;
        }
        
        @Override
        public Iterator iterator(){
            return new ArrayListIterator();
        }
        
        private class ArrayListIterator implements Iterator{
            private int currentIndex = 0;
            
            @Override
            public Object next() {
                Object o = objects[currentIndex];
                currentIndex++;
                return o;
            }
            
            @Override
            public boolean hasNext() {
                if(currentIndex >= index) return false;
                else return true;
            }
        }
    }

    LinkedList.java:

    package com.cy.dp.iterator;
    
    import com.cy.dp.iterator.Collection;
    
    public class LinkedList implements Collection {
        Node head = null;
        Node tail = null;        //最末尾的节点
        int size = 0;            //记录当前链表里面Node个数
        
        @Override
        public void add(Object o){
            Node n = new Node(o, null);
            if(head==null){
                head = n;
                tail = n;
            }
            tail.setNext(n);
            tail = n;
            size++;
        }
        
        @Override
        public int size(){
            return size;
        }
        
        //返回一个实现了Iterator接口的匿名类
        @Override
        public Iterator iterator(){
            return new Iterator(){
                Node currentNode = head;
                
                @Override
                public Object next() {
                    Object o = currentNode.getData();
                    currentNode = currentNode.getNext();
                    return o;
                }
    
                @Override
                public boolean hasNext() {
                    if(currentNode==null) return false;
                    else return true;
                }
            };
        }
    }

    Test.java 测试类:

    public class Test {
        public static void main(String[] args) {
            Collection c = new LinkedList();
            //Collection c = new ArrayList();
            
            for(int i=0; i<15; i++){
                c.add(new Cat(i));
            }
            System.out.println(c.size());
            
            Iterator it = c.iterator();
            while(it.hasNext()){
                System.out.println(it.next());
            }
            
        }
    }

    打印:

    15
    Cat [id=0]
    Cat [id=1]
    Cat [id=2]
    Cat [id=3]
    Cat [id=4]
    Cat [id=5]
    Cat [id=6]
    Cat [id=7]
    Cat [id=8]
    Cat [id=9]
    Cat [id=10]
    Cat [id=11]
    Cat [id=12]
    Cat [id=13]
    Cat [id=14]
     
     
  • 相关阅读:
    解决网站出现Error Establishing Database Connection问题
    Linux发行版时间线分支图最新版
    rem.js,移动多终端适配
    几种常用JavaScript设计模式es6
    文件上传,8种场景
    react动态添加样式:style和className
    记录我的 python 学习历程-Day13 匿名函数、内置函数 II、闭包
    记录我的 python 学习历程-Day12 生成器/推导式/内置函数Ⅰ
    记录我的 python 学习历程-Day11 两个被忽视的坑、补充知识点、函数名的应用、新版格式化输出、迭代器
    记录我的 python 学习历程-Day10 函数进阶
  • 原文地址:https://www.cnblogs.com/tenWood/p/9147940.html
Copyright © 2011-2022 走看看