【Java學習筆記】(十)LinkedList源碼分析(三)

這篇文章來自我的博客

正文之前

在前面兩篇文章中已經(jīng)講述了 LinkedList 基于列表基于隊列的操作,這一篇文章作為 LinkedList 系列文章的最后一篇,將會講述迭代器的用法:

  1. ListItr
  2. DescendingIterator

正文

1. ListItr

  1. 成員變量
  2. 構(gòu)造

在源碼中,ListItr 對象是私有的,對象的發(fā)布是通過 listIterator() 方法進行的,關(guān)于對象的發(fā)布這里不講述,先看看 listIterator() 方法是怎樣的:

    //index是從1開始的
    public ListIterator<E> listIterator(int index) {
        //先檢查給出的索引是否有效
        checkPositionIndex(index);
        //返回 ListItr 對象
        return new ListItr(index);
    }

然后看看 ListItr 類:

    private class ListItr implements ListIterator<E> {}
1. 成員變量
        //當前節(jié)點
        private Node<E> lastReturned;
        //下一個節(jié)點
        private Node<E> next;
        //下一個節(jié)點的位置
        private int nextIndex;
        private int expectedModCount = modCount;
2. 構(gòu)造
        ListItr(int index) {
            // assert isPositionIndex(index);
            //需要判斷索引是否有效,然后確定下一個節(jié)點
            next = (index == size) ? null : node(index);
            //下一個節(jié)點的位置
            nextIndex = index;
        }

傳入的參數(shù) index 是從1開始的,一試便知:

3. 增

方法中使用到了之前寫的基于列表的操作:

        public void add(E e) {
            checkForComodification();
            lastReturned = null;
            //最后一個節(jié)點
            if (next == null)
                //末尾添加
                linkLast(e);
            else
                //在指定位置添加
                linkBefore(e, next);
            //把下一個節(jié)點的位置往后移
            nextIndex++;
            expectedModCount++;
        }

        
4. 刪

方法中使用到了之前寫的基于列表的操作:

        public void remove() {
            checkForComodification();
            //如果當前節(jié)點為空
            if (lastReturned == null)
                throw new IllegalStateException();

            //定義一個節(jié)點,表示當前節(jié)點的下一個節(jié)點
            Node<E> lastNext = lastReturned.next;
            //刪除節(jié)點
            unlink(lastReturned);
            if (next == lastReturned)
                next = lastNext;
            else
                nextIndex--;
            //將當前節(jié)點設(shè)為null
            lastReturned = null;
            expectedModCount++;
        }
5. 改

將當前節(jié)點中的元素改為傳入的參數(shù):

        public void set(E e) {
            //如果節(jié)點為空
            if (lastReturned == null)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.item = e;
        }
6. 查

迭代器支持雙向操作,所以能夠向前或向后移動:

向后移動:

        //判斷是否有下一個節(jié)點
        public boolean hasNext() {
            return nextIndex < size;
        }

        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();
            //將下一個節(jié)點表示為當前節(jié)點
            lastReturned = next;
            next = next.next;
            //位置向后移動
            nextIndex++;
            //返回當前節(jié)點的元素
            return lastReturned.item;
        }

        //返回下一個節(jié)點的位置
        public int nextIndex() {
            return nextIndex;
        }

向前移動,操作是類似的:

        public boolean hasPrevious() {
            return nextIndex > 0;
        }

        public E previous() {
            checkForComodification();
            if (!hasPrevious())
                throw new NoSuchElementException();
            //向前移,并修改位置
            lastReturned = next = (next == null) ? last : next.prev;
            nextIndex--;
            //返回元素
            return lastReturned.item;
        }

        //同樣是返回位置
        public int previousIndex() {
            return nextIndex - 1;
        }

2. DescendingIterator

反向迭代器對象的發(fā)布方式也和上面的一樣,通過 descendingIterator() 來發(fā)布對象:

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

    private class DescendingIterator implements Iterator<E> {}

反向迭代器實現(xiàn)的方法就3個,我們先看一眼成員變量:

    private final ListItr itr = new ListItr(size());

其實反向迭代器是基于 ListItr 來實現(xiàn)的,直接在迭代器的初始位置設(shè)置在鏈表的末尾

接下來來看看3個方法:

        public boolean hasNext() {
            return itr.hasPrevious();
        }
        public E next() {
            return itr.previous();
        }
        public void remove() {
            itr.remove();
        }

因為這是反向的,所以向前方法的名字還是 next(),但是,是使用了 previous 來進行的

那么,有關(guān) LinkedList 的基本用法的源碼就已經(jīng)解讀完畢了,接下來會是其他容器類的源碼解讀

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容