从头开始学JDK-------ListIterator

目录

* ListIterator #新增接口方法

* ArrayList # ListItr

* ArrayList # ListItr #构造函数

* ArrayList # ListItr #hasPrevious

* ArrayList # ListItr #previousIndex

* ArrayList # ListItr #previous

* ArrayList # ListItr #set

* ArrayList # ListItr #add

* ListIterator #新增接口方法

        新增从后往前迭代的方向,并支持返回下一个或者上一个的光标。支持在迭代期间修改元素。

package java.util;

public interface ListIterator<E> extends Iterator<E> {
    
    boolean hasPrevious();

    E previous();

    int nextIndex();

    int previousIndex();

    void set(E e);

    void add(E e);
}

* ArrayList # ListItr

        ArrayList内部类中的ListItr已经继承了Itr类,说明已经实现了Iterator接口中的所有方法。剩下的需要实现的是ListIterator接口中新增的方法。

class ArrayList ...
    private class Itr implements Iterator ...

    private class ListItr extends Itr implements ListIterator<E> ...

* ArrayList # ListItr #构造函数

        成员变量完全继承于Itr,有cursor光标与上次返回的元素角标lastRet。

        构造的时候指明光标所指向的位置即可。

class ArrayList...
    public ListIterator<E> listIterator() {
        return new ListItr(0);
    }

class ListItr ...
        //extends from Itr
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such

        ListItr(int index) {
            super();
            cursor = index;
        }

* 衍生 从后向前遍历ArrayList怎么构造

        当元素从前往后迭代的时候,迭代完成的时候,ArrayList内部的Itr类的光标属性值正好等于元素个数,即 cursor = size 。

        所以构造ListIterator且希望从后想前迭代的时候,构造函数就直接把cursor的值初始化成size。

ListIterator<String> iterator = list.listIterator(lise.size());
while(iterator.hasPrevious()){
    String element = iterator.previous();
}

* ArrayList # ListItr #hasPrevious

        从后往前遍历的时候,光标等于哪个角标,就是正在迭代哪个角标的元素。

        当光标到0的时候,说明角标为0的元素已经被返回过。再前面就已经没有元素了。

class ArrayList...

  class ListItr ...

     public boolean hasPrevious(){
         //cursor = 0 means first element has been returned
         return cursor != 0;
     }

* ArrayList # ListItr #previousIndex

         前面一个元素的角标就是当前迭代元素的前一个。

class ArrayList...

  class ListItr ...

     public int previousIndex() {
            return cursor - 1;
     }

* ArrayList # ListItr #previous

         从后往前迭代,每次光标向前移动一位。指向谁,就是正在迭代谁。

class ArrayList...

  class ListItr ...

     public E previous() {
        int i = cursor - 1;
 
        check()...

        lastRet = i;
        cursor = i;
            
        return elementData[lastRet];
     }

* ArrayList # ListItr #set

        set方法就是在迭代期间,把正在迭代的这个元素替换掉。

class ArrayList...

  class ListItr ...

     public void set(E e) {
          elementData[cursor] = e;
     }

* ArrayList # ListItr #add

        add方法就是在迭代期间,把正在迭代的这个元素的后面这个位置上增加一个元素。正在迭代的元素的后一位到最后一个元素整体往后移动一位。

        比如集合【0,1,2,3,4】在迭代元素【0】的时候调用add(5)方法,迭代后的数组是【0,5,1,2,3,4】

        add方法用于从前往后变量的情况。在调用add方法之前,已经调用过next()方法,此时光标已经是指向当前迭代元素的下一个元素了。

        上面在迭代【0】的时候进行add(5)操作,需要复制【1,2,3,4】共 size:5  -  cursor:1 = 4 个元素。所以复制的个数是 size - cursor。

        从哪里开始复制呢?从原来集合角标是1的地方开始,即cursor处。

        复制到哪里去呢?从cursor = 1的后的元素【2】开始,即从 cursor + 1处开始。

class ArrayList...
  class ListItr ...
     public void add(E e) {
             //cursor point to next element of current element
             int i = cursor;

             System.arrayCopy(elementData , i , elementData, i + 1,size - i);

             //cursor still point to next element after copy
             cursor = i + 1;

             lastRet = -1;
     }

 

posted @ 2022-07-17 12:13  小大宇  阅读(5)  评论(0编辑  收藏  举报