Java8 ConcurrentLinkedDeque 源码解析

 目录

1、定义

3、add / offer / addAll

4、peek / poll / remove

5、unlinkFirst / unlinkLast

6、unlink 

7、iterator / descendingIterator


      ConcurrentLinkedDeque表示一个无固定容量的,线程安全的,基于CAS而非ReentrantLock互斥锁实现的双端队列,其实现方式跟ConcurrentLinkedQueue类似,本篇博客就详细探讨该类的实现细节。

1、定义

     ConcurrentLinkedDeque的类继承关系如下:

只实现了Deque接口,未实现BlockingDeque接口,相关方法的功能可以参考《Java8 LinkedBlockingDeque 源码解析》

该类包含的实例属性如下:

//链表头
private transient volatile Node<E> head;

//链表尾
private transient volatile Node<E> tail;

private static final int HOPS = 2;

  包含的静态属性通过static代码块初始化,如下:

其中PREV_TERMINATOR和NEXT_TERMINATOR都是两个静态常量,Node是一个静态的内部类,实现如下:

static final class Node<E> {
        volatile Node<E> prev; //前一个节点
        volatile E item; //关联的元素
        volatile Node<E> next; //下一个节点

        Node() {  // default constructor for NEXT_TERMINATOR, PREV_TERMINATOR
        }

        Node(E item) {
            UNSAFE.putObject(this, itemOffset, item);
        }
        
        //compareAndSwapObject和putOrderedObject都会保证修改对其CPU立即可见
        boolean casItem(E cmp, E val) {
            return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
        }

        void lazySetNext(Node<E> val) {
            UNSAFE.putOrderedObject(this, nextOffset, val);
        }

        boolean casNext(Node<E> cmp, Node<E> val) {
            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
        }

        void lazySetPrev(Node<E> val) {
            UNSAFE.putOrderedObject(this, prevOffset, val);
        }

        boolean casPrev(Node<E> cmp, Node<E> val) {
            return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
        }


        private static final sun.misc.Unsafe UNSAFE;
        private static final long prevOffset;
        private static final long itemOffset;
        private static final long nextOffset;
        
        //获取三个属性的偏移量
        static {
            try {
                UNSAFE = sun.misc.Unsafe.getUnsafe();
                Class<?> k = Node.class;
                prevOffset = UNSAFE.objectFieldOffset
                    (k.getDeclaredField("prev"));
                itemOffset = UNSAFE.objectFieldOffset
                    (k.getDeclaredField("item"));
                nextOffset = UNSAFE.objectFieldOffset
                    (k.getDeclaredField("next"));
            } catch (Exception e) {
                throw new Error(e);
            }
        }
    }

 2、构造方法

public ConcurrentLinkedDeque() {
         //初始化head和tail属性
        head = tail = new Node<E>(null);
    }

public ConcurrentLinkedDeque(Collection<? extends E> c) {
        // Copy c into a private chain of Nodes
        Node<E> h = null, t = null;
        //遍历集合c
        for (E e : c) {
            checkNotNull(e);
            Node<E> newNode = new Node<E>(e);
            if (h == null)
                h = t = newNode; //链表未初始化
            else {
                //插入到tail的后面
                t.lazySetNext(newNode);
                newNode.lazySetPrev(t);
                t = newNode;
            }
        }
        initHeadTail(h, t);
    }

private void initHeadTail(Node<E> h, Node<E> t) {
        if (h == t) {
            if (h == null) //两个都是空
                h = t = new Node<E>(null);
            else {
                //两个非空,即此时链表中只有一个元素,构建一个空节点作为tail
                Node<E> newNode = new Node<E>(null);
                t.lazySetNext(newNode);
                newNode.lazySetPrev(t);
                t = newNode;
            }
        }
        head = h;
        tail = t;
    }

3、add / offer / addAll

     add和offer类方法的核心就是linkFirst和linkLast方法。 

public boolean add(E e) {
        return offerLast(e);
    }

public void addFirst(E e) {
        linkFirst(e);
    }

public void addLast(E e) {
        linkLast(e);
    }

public boolean offer(E e) {
        return offerLast(e);
    }

public boolean offerFirst(E e) {
        linkFirst(e);
        return true;
    }

public boolean offerLast(E e) {
        linkLast(e);
        return true;
    }


private void linkFirst(E e) {
        checkNotNull(e);
        final Node<E> newNode = new Node<E>(e);

        restartFromHead:
        for (;;)
            for (Node<E> h = head, p = h, q;;) {
                if ((q = p.prev) != null &&     //head前面两个节点都非空
                    (q = (p = q).prev) != null)
                    //如果head节点发生变更,p等于新的head节点,否则p等于q,然后开始下一次for循环,直到有一个节点的prev为null,即找到链表最前面的一个节点
                    p = (h != (h = head)) ? h : q;
                else if (p.next == p) // 这个节点原来是head,即将被移除,重新读取head
                    continue restartFromHead;
                else {
                    //第一个的if条件不成立,p的prev为null,p就是链表中第一个节点
                    newNode.lazySetNext(p); // CAS piggyback
                    if (p.casPrev(null, newNode)) { 
                        //如果cas修改prev成功
                        if (p != h) //如果p不等于head则修改head,当p等于head的前一个节点时p就不等于head
                                    //如果等于则不修改,下一次调用此方法时再修改,相当于节省了一次casHead调用
                            //cas修改head,如果修改失败,则表示其他线程修改了head,其他线程插入节点只能插入到nowNode的后面,所以只要有一个线程修改成功即可        
                            casHead(h, newNode);  
                        return;
                    }
                    //如果修改失败,下一次for循环会重新读取p
                }
            }
    }

   
private void linkLast(E e) {
        checkNotNull(e);
        final Node<E> newNode = new Node<E>(e);

        restartFromTail:
        for (;;)
            for (Node<E> t = tail, p = t, q;;) {
                if ((q = p.next) != null &&     //如果tail后两个节点非空
                    (q = (p = q).next) != null)
                    //tail是否改变,如果变了p等于tail,否则等于q,继续下一次循环直到找到next为null的节点,即链表中最后一个节点
                    p = (t != (t = tail)) ? t : q;
                else if (p.prev == p) //该节点原来是tail节点,即将被移除,重新读取tail
                    continue restartFromTail;
                else {
                    // p is last node
                    newNode.lazySetPrev(p); // CAS piggyback
                    if (p.casNext(null, newNode)) {
                        //cas修改成功,newNode作为p的下一个节点
                        //同上,p等于t不修改tail,下一次调用时p不等于t则修改tail
                        if (p != t) // hop two nodes at a time
                            casTail(t, newNode);  //只有一个线程修改成功即可,因为cas本身保证了链表的节点顺序
                        return;
                    }
                    //cas失败重新for循环找到链表最后一个节点
                }
            }
    }

public boolean addAll(Collection<? extends E> c) {
        if (c == this)
            throw new IllegalArgumentException();

        Node<E> beginningOfTheEnd = null, last = null;
        //遍历集合c,将其中的元素转换成一个链表
        for (E e : c) {
            checkNotNull(e);
            Node<E> newNode = new Node<E>(e);
            if (beginningOfTheEnd == null)
                beginningOfTheEnd = last = newNode;//初始化链表
            else {
                last.lazySetNext(newNode); //插入到链表的后面
                newNode.lazySetPrev(last);
                last = newNode;
            }
        }
        if (beginningOfTheEnd == null) //链表为空
            return false;

        //将beginningOfTheEnd作为一个新节点原子的插入到链表后面,同上面的linkLast逻辑
        restartFromTail:
        for (;;)
            for (Node<E> t = tail, p = t, q;;) {  //如果tail后两个节点非空
                if ((q = p.next) != null &&
                    (q = (p = q).next) != null)
                    p = (t != (t = tail)) ? t : q;
                else if (p.prev == p) //p原来是tail节点,即将被移除
                    continue restartFromTail;
                else {
                    //p是最后一个节点
                    beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
                    if (p.casNext(null, beginningOfTheEnd)) { //插入到p的后面成功
                        if (!casTail(t, last)) { //如果修改tail失败进入if分支,如果修改成功直接返回
                            //重新读取tail
                            t = tail;
                            if (last.next == null) //没有新的节点插入到last后面,再次尝试修改,如果有新的节点插入了,则插入新节点的线程会负责修改tail
                                casTail(t, last);
                        }
                        return true;
                    }
                    // Lost CAS race to another thread; re-read next
                }
            }
    }

private boolean casHead(Node<E> cmp, Node<E> val) {
        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
    }

private boolean casTail(Node<E> cmp, Node<E> val) {
        return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
    }

4、peek / poll / remove

public E peek()           { return peekFirst(); }

public E peekFirst() {
        //first返回链表的第一个节点,succ返回p的下一个有效节点
        for (Node<E> p = first(); p != null; p = succ(p)) {
            E item = p.item;
            //插入链表中的节点item都是非null的,但是poll方法移除节点前会将item置为null然后再移除
            if (item != null) //如果item为null则返回下一个有效节点
                return item;
        }
        return null;
    }

public E peekLast() {
        //last返回链表的最后一个节点,pred返回p的前一个有效节点
        for (Node<E> p = last(); p != null; p = pred(p)) {
            E item = p.item;
            if (item != null)
                return item;
        }
        return null;
    }

public E poll()           { return pollFirst(); }

public E pollFirst() {
        for (Node<E> p = first(); p != null; p = succ(p)) {
            E item = p.item;
            if (item != null && p.casItem(item, null)) {
                //成功的将item修改为null,表示该节点即将从链表中移除
                //unlink将目标节点从链表移除
                unlink(p);
                return item;
            }
        }
        return null;
    }

public E pollLast() {
        for (Node<E> p = last(); p != null; p = pred(p)) {
            E item = p.item;
            if (item != null && p.casItem(item, null)) {
                unlink(p);
                return item;
            }
        }
        return null;
    }

public E remove()         { return removeFirst(); }

public E removeFirst() {
        return screenNullResult(pollFirst());
    }

public E removeLast() {
        return screenNullResult(pollLast());
    }

public boolean remove(Object o) {
        return removeFirstOccurrence(o);
    }

public boolean removeFirstOccurrence(Object o) {
        checkNotNull(o);
        //从first开始往后遍历
        for (Node<E> p = first(); p != null; p = succ(p)) {
            E item = p.item;
            if (item != null && o.equals(item) && p.casItem(item, null)) {
                //找到目标节点,将item置为null并从链表中移除
                unlink(p);
                return true;
            }
        }
        return false;
    }

public boolean removeLastOccurrence(Object o) {
        checkNotNull(o);
        //从last往前遍历
        for (Node<E> p = last(); p != null; p = pred(p)) {
            E item = p.item;
            if (item != null && o.equals(item) && p.casItem(item, null)) {
                //找到目标节点,将item置为null并从链表中移除
                unlink(p);
                return true;
            }
        }
        return false;
    }

//返回链表中第一个节点
Node<E> first() {
        restartFromHead:
        for (;;)
            for (Node<E> h = head, p = h, q;;) {
                if ((q = p.prev) != null &&   //如果head的前2个节点非空
                    (q = (p = q).prev) != null)
                    //head变了,p等于新的head,否则等于q,重新循环直到找到prev为null的节点
                    p = (h != (h = head)) ? h : q;
                else if (p == h            //如果p等于head 或者p不等于head,将p修改成head成功,返回p
                         || casHead(h, p))
                    return p;
                else
                    //casHead失败,有其他线程修改了head,for循环重新读取head
                    continue restartFromHead;
            }
    }

final Node<E> succ(Node<E> p) {
        //如果p等于q,p原来是head节点即将被移除,重新获取head节点,否则就是下一个节点
        Node<E> q = p.next;
        return (p == q) ? first() : q;
    }

 Node<E> last() {
        restartFromTail:
        for (;;)
            //逻辑跟first基本相同
            for (Node<E> t = tail, p = t, q;;) {
                if ((q = p.next) != null &&   //如果tail的后2个节点非空
                    (q = (p = q).next) != null)
                    p = (t != (t = tail)) ? t : q;
                else if (p == t           //如果p等于tail则返回
                         || casTail(t, p))
                    return p;
                else
                    //casTail失败,重新读取tail
                    continue restartFromTail;
            }
    }

 final Node<E> pred(Node<E> p) {
        Node<E> q = p.prev;
        //p等于q说明p即将被移除,重新读取tail,否则返回前一个节点
        return (p == q) ? last() : q;
    }

//如果为空抛出异常
 private E screenNullResult(E v) {
        if (v == null)
            throw new NoSuchElementException();
        return v;
    }

5、unlinkFirst / unlinkLast

      这两个分别用于移除链表头和链表尾节点,如果链表头的下一个节点,链表尾的上一个节点的item都不为null,则直接返回,并不会直接移除。如果item为null且存在其他节点时,才会真正的移除,并重置head和tail节点。

private void unlinkFirst(Node<E> first, Node<E> next) {
        // assert first != null;
        // assert next != null;
        // assert first.item == null;
        for (Node<E> o = null, p = next, q;;) {
            if (p.item != null     //p节点是一个有效节点
                || (q = p.next) == null) { //p是最后一个节点
                //o在第一遍循环时为null,不会进入此if分支
                //next节点的item为null,即该节点也是需要被移除的,next节点后还有其他节点时就会进入else分支,再次for循环如果p.item不为null
                //或者p是最后一个节点就会进入下面的if分支
                if (o != null && p.prev != p && first.casNext(next, p)) {
                     //casNext修改成功会将first到p之间的item为null的多个节点都从链表中移除了,此时只是first的next属性修改了,但是p的prev属性未修改
                     //skipDeletedPredecessors就是修改p的prev属性,将前面的item为null的需要被移除的节点都跳过
                    skipDeletedPredecessors(p);
                    if (first.prev == null &&  //first还是head节点
                        (p.next == null || p.item != null) && //p是最后一个节点或者p是一个有效节点
                        p.prev == first) { //p的prev属性指向first
                        
                        //调整head和tail节点
                        updateHead(); // Ensure o is not reachable from head
                        updateTail(); // Ensure o is not reachable from tail

                        //将o从链表中移除
                        o.lazySetNext(o);
                        o.lazySetPrev(prevTerminator());
                    }
                }
                //第一遍for循环进入此if分支后就直接返回了,即没有实际的移除节点
                return;
            }
            //p.item为null,q不为null时进入下面的分支,即可能存在多个item为null的节点
            else if (p == q) //p本身即将被移除,p移除了,p的前面的多个节点因为链表关系被破坏了也会移除
                return;
            else {
                //p等于q,继续遍历下一个节点
                o = p;
                p = q;
            }
        }
    }

   
private void unlinkLast(Node<E> last, Node<E> prev) {
        // assert last != null;
        // assert prev != null;
        // assert last.item == null;
        for (Node<E> o = null, p = prev, q;;) {
            if (p.item != null || (q = p.prev) == null) {
                //第一遍for循环进入if分支时,o为null,直接return了,即没有实际移除节点
                //进入最下面的else分支后,找到了一个有效节点或者遍历到链表的第一个节点,此时已跳过多个item为null的节点
                if (o != null && p.next != p && last.casPrev(prev, p)) {
                    //将p作为last的prev属性,skipDeletedSuccessors会修改p的next属性,让其指向last
                    skipDeletedSuccessors(p);
                    //last和p的属性都调整后,last和p之间的item为null的节点就从链表中移除了
                    if (last.next == null &&
                        (p.prev == null || p.item != null) &&
                        p.next == last) {
                        
                        //调整head和tail
                        updateHead(); // Ensure o is not reachable from head
                        updateTail(); // Ensure o is not reachable from tail

                        //将o从链表中移除
                        o.lazySetPrev(o);
                        o.lazySetNext(nextTerminator());
                    }
                }
                return;
            }
            //p的item为null且p还有前一个节点,说明有多个为null的节点
            else if (p == q) //p已经从链表移除
                return;
            else {
                //继续遍历前面的一个节点,直到找到一个有效节点或者遍历到链表的第一个节点
                o = p;
                p = q;
            }
        }
    }

private void skipDeletedPredecessors(Node<E> x) {
        whileActive:
        do {
            Node<E> prev = x.prev;
            // assert prev != null;
            // assert x != NEXT_TERMINATOR;
            // assert x != PREV_TERMINATOR;
            Node<E> p = prev;
            findActive:
            for (;;) {
               //正常情况x的前一个节点的item为null,如果不为null,说明该节点是有效节点,则终止内层的for循环
               //将该节点设置为x的prev节点
                if (p.item != null)  
                    break findActive;
                //p.item为null    
                Node<E> q = p.prev;
                if (q == null) { //p是链表第一个节点
                    if (p.next == p)  //p即将被移除,内存for循环终止,继续外层do/while循环,处理prev的前一个节点
                        continue whileActive;
                    break findActive; //p是一个有效节点,终止内层的for循环
                }
                else if (p == q) //该节点也是无效的,内存for循环终止,继续外层do/while循环,处理prev的前一个节点
                    continue whileActive;
                else
                    //p不等于q,p前面还有其他节点,则继续for循环遍历其他节点
                    p = q;
            }

            //如果p不等于prev则将x的prev属性设置为p
            if (prev == p || x.casPrev(prev, p))
                return;
        //x.item不为null,说明x是一个有效节点,x的next为null说明x是链表最后一个节点,这两条件都不满足则终止循环
        //满足这两条件时需要正确的设置prev属性,否则可以忽略
        } while (x.item != null || x.next == null);
    }

    private void skipDeletedSuccessors(Node<E> x) {
        whileActive:
        do {
            Node<E> next = x.next;
            // assert next != null;
            // assert x != NEXT_TERMINATOR;
            // assert x != PREV_TERMINATOR;
            Node<E> p = next;
            findActive:
            for (;;) {
                //找到一个有效节点,则终止内层的for循环,将该节点设置为x的next节点
                if (p.item != null) 
                    break findActive;
                //p的item为null    
                Node<E> q = p.next;
                if (q == null) { //p是链表最后一个节点了
                    if (p.prev == p)  //p即将被移除,内存for循环终止,继续外层do/while循环,处理next的下一个节点
                        continue whileActive;
                    break findActive; //终止内层的for循环
                }
                else if (p == q)  //p即将被移除,内存for循环终止,继续外层do/while循环,处理next的下一个节点
                    continue whileActive;
                else
                    p = q; //继续处理下一个节点
            }

            //如果next不等于p,将p作为x的next节点
            if (next == p || x.casNext(next, p))
                return;
         //x.item不为null,说明x是一个有效节点,x的prev为null说明x是链表第一个节点,这两条件都不满足则终止循环
        } while (x.item != null || x.prev == null);
    }

//从head节点往前遍历找到链表的第一个节点,将其置为head
private final void updateHead() {
        Node<E> h, p, q;
        restartFromHead:
        while ((h = head).item == null   //head的item为null说明head需要被移除
                   && (p = h.prev) != null) { //head的前一个节点不为null,说明head可以被前面的节点替换
            for (;;) {
                if ((q = p.prev) == null ||  //如果p就是链表的第一个节点
                    (q = (p = q).prev) == null) { //如果q是链表的第一个节点,此时p等于q
                    //将head修改为p,p是链表的第一个节点
                    if (casHead(h, p))
                        return;
                    else
                       //修改head失败,终止内层for循环,继续外层while循环,重新读取head
                        continue restartFromHead;
                }
                else if (h != head) //如果head变了,重新读取head
                    continue restartFromHead;
                else
                    p = q; //遍历前一个节点
            }
        }
    }

//从tail节点往后遍历找到链表最后一个节点,将其置为tail    
private final void updateTail() {
        // Either tail already points to an active node, or we keep
        // trying to cas it to the last node until it does.
        Node<E> t, p, q;
        restartFromTail:
        //tail的item为null需要被移除,且存在下一个节点
        while ((t = tail).item == null && (p = t.next) != null) {
            for (;;) {
                if ((q = p.next) == null ||
                    (q = (p = q).next) == null) {
                    //找到了链表最后一个几点,将tail修改为p
                    if (casTail(t, p))
                        return;
                    else
                        //修改失败,重新读取p
                        continue restartFromTail;
                }
                else if (t != tail)
                    continue restartFromTail; //tail变了,重新读取p
                else
                    p = q; //遍历下一个节点
            }
        }
    }

@SuppressWarnings("unchecked")
    Node<E> prevTerminator() {
        return (Node<E>) PREV_TERMINATOR;
    }

    @SuppressWarnings("unchecked")
Node<E> nextTerminator() {
        return (Node<E>) NEXT_TERMINATOR;
    }

6、unlink 

      unlink方法用于从链表中移除某个节点,该节点可以是链表头或者链表尾或者是链表中间的某个节点。unlink方法不是每次都将节点从链表中完全移除的,而是有延迟,一次移除时可能会将多个item为null的节点从链表中移除。注意item为null表示这个节点需要被移除,prev或者next属性指向自己,表明这个节点周围的多个节点可能都被移除了,不需要再遍历该节点的前后节点了,而是重新从head或者tail节点遍历。

 void unlink(Node<E> x) {
        // assert x != null;
        // assert x.item == null;
        // assert x != PREV_TERMINATOR;
        // assert x != NEXT_TERMINATOR;

        final Node<E> prev = x.prev;
        final Node<E> next = x.next;
        if (prev == null) {
            //x是链表头节点
            unlinkFirst(x, next);
        } else if (next == null) {
            //x是链表尾节点
            unlinkLast(x, prev);
        } else {
            //移除链表中间的某个节点
            Node<E> activePred, activeSucc;
            boolean isFirst, isLast;
            int hops = 1;

            //往前遍历找到第一个有效的节点
            for (Node<E> p = prev; ; ++hops) {
                if (p.item != null) { //找到一个有效节点,终止循环
                    activePred = p;
                    isFirst = false;
                    break;
                }
                //p.item为null
                Node<E> q = p.prev;
                if (q == null) { //p是链表第一个节点
                    if (p.next == p) //p是无效节点,p周围的节点可能都会被移除,再遍历无意义,下一次unlink时会删除该节点
                        return;
                    activePred = p;
                    isFirst = true;
                    break;
                }
                else if (p == q) //p是无效节点
                    return;
                else
                    p = q; //继续遍历前一个节点
            }

            //往后遍历找到第一个有效的节点
            for (Node<E> p = next; ; ++hops) {
                if (p.item != null) { //找到一个有效节点,终止循环
                    activeSucc = p;
                    isLast = false;
                    break;
                }
                Node<E> q = p.next; 
                if (q == null) {  //p是链表最后一个节点
                    if (p.prev == p) //p是无效节点,p周围的节点可能都会被移除,再遍历无意义
                        return;
                    activeSucc = p;
                    isLast = true;
                    break;
                }
                else if (p == q) //p是无效节点
                    return;
                else
                    p = q; //继续遍历下一个节点
            }

            // HOPS等于2,如果上面两个for循环都只循环了一次就找到了有效节点
            if (hops < HOPS
                // always squeeze out interior deleted nodes
                && (isFirst | isLast)) //如果x是链表第二个节点或者顺数第二个节点
                return;

            //调整activePred的next属性,将activePred到next节点之间的节点从链表中移除
            skipDeletedSuccessors(activePred);
            //调整activeSucc的prev属性
            skipDeletedPredecessors(activeSucc);

            // Try to gc-unlink, if possible
            if ((isFirst | isLast) && 
                (activePred.next == activeSucc) && //activePred和activeSucc连在一起了,中间的x就被移除了
                (activeSucc.prev == activePred) &&
                (isFirst ? activePred.prev == null : activePred.item != null) && //x是链表头第二个节点,如果不是item不为null
                (isLast  ? activeSucc.next == null : activeSucc.item != null)) {  //x是链表倒数第二个节点,如果不是item不为null
                
                //更新链表头和链表尾
                updateHead(); // Ensure x is not reachable from head  
                updateTail(); // Ensure x is not reachable from tail

                //重置x的prev和next属性,将其从链表中移除
                x.lazySetPrev(isFirst ? prevTerminator() : x);
                x.lazySetNext(isLast  ? nextTerminator() : x);
            }
        }//else结束
    }


7、iterator / descendingIterator

public Iterator<E> iterator() {
        return new Itr();
    }

public Iterator<E> descendingIterator() {
        return new DescendingItr();
    }

  Itr和DescendingItr都是内部类,继承自另一个内部类AbstractItr,这两个的定义如下:

  AbstractItr的实现如下:

private abstract class AbstractItr implements Iterator<E> {
        //下一次next方法返回的节点
        private Node<E> nextNode;

         //下一次next方法返回的元素
        private E nextItem;

        //上一次next方法返回的节点
        private Node<E> lastRet;

        abstract Node<E> startNode();
        abstract Node<E> nextNode(Node<E> p);

        AbstractItr() {
            advance();
        }

        private void advance() {
            lastRet = nextNode;
            //构造方法调用时nextNode为null
            Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
            //nextNode是下一次for循环时调用的
            for (;; p = nextNode(p)) {
                if (p == null) {
                    //链表为空或者无有效节点
                    nextNode = null;
                    nextItem = null;
                    break;
                }
                E item = p.item;
                if (item != null) { //nextNode和nextItem赋值
                    nextNode = p;
                    nextItem = item;
                    break;
                }
                //item为null则调用nextNode获取下一个节点
            }
        }

        public boolean hasNext() {
            return nextItem != null;
        }

        public E next() {
            E item = nextItem;
            if (item == null) throw new NoSuchElementException();
            advance();
            return item;
        }

        public void remove() {
            Node<E> l = lastRet;
            if (l == null) throw new IllegalStateException();
            l.item = null; //item置为null
            unlink(l);  //从链表中移除
            lastRet = null;
        }
    }

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值