java迭代器模式

迭代器模式

提供一种方法顺序访问一个集合对象中的各个元素,而又不暴露该对象的内部细节

迭代器(Iterator)

public interface Iterator<E> {
	//判断是否可继续迭代下去,即如果next返回元素而不是抛出异常,则返回true。
    boolean hasNext();
	//返回迭代中的下一个元素,如果迭代没有更多元素,抛出没有元素异常(NoSuchElementException)
    E next();
    //默认情况下迭代中禁止对象的修改
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    //默认迭方法
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

可迭代对象(Iterable)

public interface Iterable<T> {
	//返回一个迭代器
    Iterator<T> iterator();
    //迭代过程,对iterable的每个元素执行给定的操作,可能引发并行修改异常
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    //Spliterator就是为了并行遍历元素而设计的一个迭代器
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

从ArrayList理解迭代器模式

继承结构
接口Collection继承Iterable 接口
接口List 继承 Collection接口
类 ArrayList 实现 List接口

ArrayList实现Iterable的iterator()方法:

	//返回一个迭代器
    public Iterator<E> iterator() {
    	//Itr是ArrayList 的一个内部类
        return new Itr();
    }

ArrayList内部类Itr

 //从AbstractList继承到的一个属性
 protected transient int modCount = 0;//不可序列化得一个属性,计数表在结构上被修改的次数,结构修改是指那些改变列表大小的修改,用于并发检验
 private int size;// size是ArrayList的一个属性,表示集合的元素数量
 private class Itr implements Iterator<E> {
        int cursor;       // 下一个要返回的元素的索引
        int lastRet = -1; // 最后一个返回的元素的索引;如果没有,则为-1
        int expectedModCount = modCount;//expectedModCount 预期修改计数

        // 空构造方法
        Itr() {}
        public boolean hasNext()
            return cursor != size;
        }
        public E next() {
            //检查并行修改异常
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            //elementData存储arraylist元素的数组缓冲区
            //ArrayList.this.elementData为Itr外部类的ArrayList的elementData属性引用
            Object[] elementData = ArrayList.this.elementData;
            //如果下一个要返回的元素的索引超过了集合的元素的数量,意味着集合结构被修改,抛出并行修改异常
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            //返回下一个元素,lastRet 记录返回的元素的索引
            return (E) elementData[lastRet = i];
        }
        //移除集合元素
	    public void remove() {
	    
            if (lastRet < 0)
                throw new IllegalStateException();//如果未执行next()操作,将抛出非法状态异常
                
            checkForComodification();//检查并行修改异常

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;//重新记录修改计数
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
		//对剩余的每个元素执行给定的操作,直到所有元素都被处理或操作引发异常为止。
        @Override
        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i < size) {
                final Object[] es = elementData;
                if (i >= es.length)
                    throw new ConcurrentModificationException();
                for (; i < size && modCount == expectedModCount; i++)
                    action.accept(elementAt(es, i));
                // 在末尾更新一次以减少堆写入流量
                cursor = i;
                lastRet = i - 1;
                checkForComodification();
            }
        }
        //检查并行修改异常
        final void checkForComodification() {
        	//如果ArrayList大小结构被修改,抛出并行修改异常
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

写一个简单的测试

import java.util.Iterator;

public class TestIterable<E> implements Iterable<E>{
	private int start;
	private int  end;
	private E[] data;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Integer[] data=new Integer[] {1,2,3,4,5,6,7,8,9};
		TestIterable<Integer> test=new TestIterable<Integer>(data);
		for(Integer t:test) {
			System.out.print(t);
		}
		System.out.println("\n-----");
		test.forEach(System.out::print);
	}
	public TestIterable( E[] data) {
		this.data=data;
	}
	public Iterator<E> iterator() {
		// TODO Auto-generated method stub
		return new MyIterator();
	}
	class MyIterator implements Iterator<E> {
		private int index=-1;
		@Override
		public boolean hasNext() {
			return ++index<data.length;
		}
		@Override
		public E next() {
			return data[index];
		}
		
	}

}

结果输出

123456789
-----
123456789

(JDK源码就是最好的学习资料)

猜你喜欢

转载自blog.csdn.net/qq_39464369/article/details/89419318
今日推荐