zoukankan      html  css  js  c++  java
  • 被用到炉火纯清的迭代器模式

    0x01:迭代器模式简介

    Java中可以说已经把迭代器模式用到了极致,每一个集合类都关联了一个迭代器类Iterator。

    迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。UML类图如下:

    其中,Aggregate是聚集抽象类,负责提供创建具体迭代器角色的接口;Iterator是迭代抽象类,用于定义得到开始对象、得到下一个对象、判断是否到结尾、当前对象等抽象方法,统一接口;ConcreteAggregate是具体聚集类,继承Aggregate;ConcreteIterator是具体迭代器类,继承Iterator,实现开始、下一个、是否结尾、当前对象等方法。具体角色说明:

    • Iterator(迭代器):迭代器定义访问和遍历元素的接口;

    • ConcreteIterator (具体迭代器):具体迭代器实现迭代器接口,对该聚合遍历时跟踪当前位置;

    • Aggregate (聚合):聚合定义创建相应迭代器对象的接口;

    • ConcreteAggregate (具体聚合):具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例;

    0x02:迭代器模式实现

    抽象聚合:负责提供接口,比如定义一个类似createIterator()这样的方法,在Java集合类里一般是iterator()方法。
    
    public interface Aggregate {
    
        public void add(Object object);
    
        public void remove(Object object);
    
        public Iterator iterator();
    
    }
    

    抽象迭代器:负责定义访问和遍历元素的接口,基本上有固定的三个方法,即first()获取第一个元素、next()访问下一个元素、hasNext()判断已经遍历到最后。

    public interface Iterator {
    
        public Object next();    //遍历到下一个元素
    
        public boolean hasNext();    //是否已经遍历到尾部
    
        public boolean remove();    //删除当前指向的元素
    
    }
    

    具体聚合

    public class ConcreteAggregate implements Aggregate {
    
        private List list = new ArrayList();
    
        @Override
        public void add(Object object) {
            this.list.add(object);
        }
    
        public void remove(Object object) {
            this.list.remove(object);
        }
    
        @Override
        public Iterator iterator() {
            return new ConcreteIterator(this.list);
        }
    
    }
    

    具体迭代器:简单的实现就是通过一个游标,在一个容器中前后移动,遍历所有它需要查看的元素

    public class ConcreteIterator implements Iterator {
    
        private List list= new ArrayList();
        public int cursor = 0;    //定义当前游标
    
        public ConcreteIterator(List list) {
            this.list= list;
        }
    
        @Override
        public Object next() {
            Object result = null;
            if (this.hasNext()) {
                result = this.list.get(this.cursor);
                this.cursor = this.cursor + 1;
            } else {
                result = null;
            }
            return result;
        }
    
        @Override
        public boolean hasNext() {
            if (this.cursor == this.list.size()) {
                return false;
            }
            return true;
        }
    
        @Override
        public boolean remove() {
            this.list.remove(this.cursor);
            return true;
        }
    
    }
    

    迭代器模式测试代码

    注意引入自己定义的Iterator类,而不是Java内部封装好的java.util.Iterator类。

    public class Client {
    
        public static void main(String[] args) {
            Aggregate aggregate = new ConcreteAggregate();
            aggregate.add("java乐园");
            aggregate.add("架构师知音");
            aggregate.add("非常架构");
    
            //遍历
            Iterator iterator = aggregate.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
        }
    
    }
    

    0x03:JDK中的迭代器源码分析

    在JDK涉及到的迭代器Iterator都与集合有关,主要相关实现在java.util包下。下面以 ArrayList 为例进行分析:

    java.lang.Iterable类:表示一个可以被迭代的对象

    public interface Iterable<T> {
    
        Iterator<T> iterator();
    
        default void forEach(Consumer<? super T> action) {
            Objects.requireNonNull(action);
            for (T t : this) {
                action.accept(t);
            }
        }
    
        default Spliterator<T> spliterator() {
            return Spliterators.spliteratorUnknownSize(iterator(), 0);
        }
    }
    

    java.util.Iterator:表示抽象迭代器

    public interface Iterator<E> {
        boolean hasNext();
        E next();
    
        default void remove() {
            throw new UnsupportedOperationException("remove");
        }
    
        default void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            while (hasNext())
                action.accept(next());
        }
    }
    

    java.util.Collection:表示抽象聚合对象

    public interface Collection<E> extends Iterable<E> {
        
        Iterator<E> iterator();
    
        boolean add(E e);
    
        boolean remove(Object o);
    
        boolean addAll(Collection<? extends E> c);
    
        boolean removeAll(Collection<?> c);
    
        //其他省略
         .......
    
    }
    

    java.util.AbstractList.Itr:具体迭代器实现类,该类是 java.util.AbstractList 类的一个内部类

    private class ListItr extends Itr implements ListIterator<E> {
            //具体代码省略
            .......
    }
    

    java.util.ArrayList:具体聚合对象

    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
         //具体代码省略
         .......
    }
    

    java.util.ArrayList整体实现UML类图

    [来源:https://www.alicharles.com/article/design-pattern/jdk-iterator-pattern/]

    研读JDK源码的迭代器模式,可以非常有效的学习和理解迭代器模式。从代码上看JDK的迭代器源码比小编实现的复杂很多,但是基本原理无两。常常研读大神的源码有利于提升技术能力。

  • 相关阅读:
    查看Java中每个数据类型所占的位数,和表示数值的范围,并得出结论。
    同名变量的屏蔽原则
    反码,补码,原码
    机器学习概念性知识总结
    图的最短路径问题
    System Design 笔记及代码(系统设计)
    2016网易游戏实习算法题解(今年找暑期实习的时候参加的)
    Google java style
    18.1---不用加号的加法(CC150)
    Java模板模式(template)
  • 原文地址:https://www.cnblogs.com/happyhuangjinjin/p/14225025.html
Copyright © 2011-2022 走看看