Iterator、ListIterator迭代器源码分析

一、迭代器Iterator

迭代器是一种设计模式,提供了一种方法来对集合、容器进行遍历的方式。不需要关注底层的数据结构和数据类型,来达到底层和上层的遍历解耦的目的。

迭代器提供了三种方法,对集合进行遍历
1. boolean hasNext();  判断集合是否还有元素,有则返回ture,没有返回false
2. E next(); 返回下一个元素,返回当前元素的数据类型,如果到达集合结尾则抛出NoSuchElementException异常
3. void remove();删除上次访问返回的元素,删除的时候需要注意,用的不恰当会产生非法异常问题

注意
hasNext和next出现次数一样,出现次数差为奇数会抛出空指针异常,偶数则会打印两次,hasNext和remove也是轮着出现

迭代器的实现代码:
 Iterator<Integer> iterator = collection.iterator();创建一个Integer类型的迭代器
        while (iterator.hasNext()) { //集合有元素则进入循环
            Integer value = iterator.next();  // 将当前的值返回给value
            //iterator.remove(); //删除元素
            System.out.print(value + " "); //打印集合中的元素
        }

返回迭代器的集合可以使用for each语句(增强for循环)处理:(实际上它的底层实现也是通过迭代器)

 for (Integer i :collection) {
     System.out.println(i+" ");
       }
自定义迭代器:

在这里插入图片描述

  1. 需要实现Iterable接口
    implements Iterable<T>
  2. 需要重写iterator()方法
@Override   
    public Iterator<T> iterator() {
        return new Itr();
    }
自定义迭代器代码:
 //实现Iterable<T>接口
public class IteratorSelf2192<T> implements Iterable<T> {
    private T[] data;//存储元素数组
    private int size; //元素个数

    //构造函数
    public IteratorSelf2192(){
        this(10);  //容量
    }
    public IteratorSelf2192(int capacity){
        if (capacity < 0){
            try {
                throw new IllegalAccessException("参数异常");
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        data = (T[]) new Object[capacity];
        size = 0;
    }

    //判满
    public boolean isFull(){
        if(data.length == size) {
            return true;
        }
        return false;
    }

    //扩容  1.5倍
    public void grow1(){
       int newCapacity = size + (size >> 1);
       data = Arrays.copyOf(data,newCapacity);
    }

    //下标范围判断
    private boolean checkRange(int index) {
        if (index< 0 || index > size)
            throw new IndexOutOfBoundsException();
         return true;
    }
    //重写toString方法
    @Override
    public String toString() {
    StringBuffer buffer = new StringBuffer();
    for(int i = 0; i < size;i++) {

        buffer.append(data[i] + " ");
    }
    return buffer.toString();
    }

    //添加
    public boolean add(T e){
        if(isFull()){  //满则扩容
            grow1();
        }else{
            data[size++] = e;
        }
        return true;
    }
    //获取
    public T get(int index){
    checkRange(index); //下标范围检查
    return data[index];
    }
    //删除
    public T remove(int index){
   checkRange(index);
   T v = data[index];
   int mov = size - index -1;
   System.arraycopy(data,index+1,data,index,mov); //把所删除后的数据整体向前移动一位
   data[--size] = null; //最后一位置空,容量-1
      return v ;
    }
    public boolean remove (T e) {
        if (e == null) {  //对象为空
            for (int i = 0; i < size; i++) {
                if (data[i] == null) {
                    int mov = size -i-1;
                    System.arraycopy(data, i+1, data,i,mov);
                    data[--size] = null;
                    return true;
                }
            }
        } else {  //对象非空
            for (int i = 0; i < size; i++) {
                if (e.equals(data[i])) {
                    int mov = size -i-1;
                    System.arraycopy(data, i+1, data,i,mov);
                    data[--size] = null;
                    return true;
                }
            }
        }
        return false;
    }

    @Override   //重写Iterator方法
    public Iterator<T> iterator() {
        return new Itr();
    }


    class Itr implements Iterator<T>{  //内部类实现迭代器
       int afterIndex; //afterindex前一个位置
        int beforeIndex = -1;//beforeindex后一个位置

        @Override
        public boolean hasNext() { //判断集合是否还有元素  判断index是否等于size
            return afterIndex != size;
        }

        @Override
        public T next() {  //返回当前位置的数据
            int i = afterIndex;
            if(i > size) throw new IndexOutOfBoundsException();
            afterIndex+=1;
            T v = data[i];
            beforeIndex = i;
            return v;
        }
        @Override
        public void remove() { // 删除元素
        //此处调用集合的删除方法
            IteratorSelf2192.this.remove(beforeIndex);
            afterIndex = beforeIndex;
            beforeIndex = -1;
        }
    }

    public static void main(String[] args) {
        IteratorSelf2192<Integer> arrayList = new IteratorSelf2192<Integer>();
        arrayList.add(1);
        arrayList.add(4);
        arrayList.add(6);
        arrayList.add(2);

        System.out.println(arrayList);

        arrayList.remove(0); //删除0号元素
        System.out.println(arrayList);

        //迭代器iterator遍历打印
        Iterator<Integer> iterator = arrayList.iterator();
        while(iterator.hasNext()){
            Integer value = iterator.next();
            System.out.print(value + " ");
        }
        System.out.println( );
        System.out.println(arrayList.size);
    }
}

执行结果:

在这里插入图片描述

ListIterator分析:

在这里插入图片描述在这里插入图片描述
查看源码,ListIterator中有9个方法,其中和Iterator相同的有hasNext()、next()和remove()。
在这里插入图片描述
常用方法使用

  1. hashPrevious()、 previous():逆向遍历集合
 System.out.print("previous: ");
        ListIterator<Integer> listIterator1 = arrayList.listIterator(arrayList.size());
        while (listIterator1.hasPrevious()) {
            listIterator1.previousIndex();
            System.out.print(listIterator1.previous()+" "); //逆向输出集合
        }
iterator和listIterator的联系与区别?
  1. ListIterator有add()方法,可以向List中添加对象,而Iterator不能

  2. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,
    但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator不可以

  3. ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能

  4. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值