国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

LinkedList源碼淺析

DC_er / 2615人閱讀

摘要:重要方法在鏈尾添加元素除了這個方法以外,還提供了等一些方法,都是為實現(xiàn)和方法服務的,因為雙向鏈表的原因,這些實現(xiàn)都很簡單。

類聲明

LinkedList類聲明如下:

public class LinkedList
    extends AbstractSequentialList
    implements List, Deque, Cloneable, java.io.Serializable

可以發(fā)現(xiàn) LinkedList繼承了 AbstractSequentialList抽象類,而不是像 ArrayListVector那樣實現(xiàn) AbstractList,實際上,java類庫中只有 LinkedList繼承了這個抽象類,正如其名,它提供了對序列的連續(xù)訪問的抽象:


LinkedList的底層是 Deque雙向鏈表,實現(xiàn)了 Deque接口,而 Deque接口繼承于 Queue接口,因此,在java中,如果要實現(xiàn)隊列,一般都使用 LinkedList來實現(xiàn)。

Node結點

LinkedList中關于鏈表結點的定義如下:

private static class Node {
        E item;
        Node next;
        Node prev;

        Node(Node prev, E element, Node next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

每個結點都有一個前驅和后繼結點,并且在 LinkedList中也定義了兩個變量分別指向鏈表中的第一個和最后一個結點:

transient Node first;
transient Node last;
構造方法

LinkedList中只有兩個構造方法,無參數(shù)的和帶有 Collection參數(shù)的:

public LinkedList() {
}
    
public LinkedList(Collection c) {
        this();
        addAll(c);
}

重點看一下第二個構造方法,它調用了 addAll()

public boolean addAll(Collection c) {
        return addAll(size, c);
    }

這個方法將指定的 Collection添加到鏈表的結尾,如果在添加的過程中對 Collection進行了修改,則結點是不確定的。

public boolean addAll(int index, Collection c) {
        checkPositionIndex(index);//檢查是否越界
        Object[] a = c.toArray();
        int numNew = a.length;
        if (numNew == 0)
            return false;
        Node pred, succ;
        if (index == size) { //如果succ是null,說明是在結尾添加,如果不是,記錄index處的結點
            succ = null;
            pred = last;
        } else {
            succ = node(index);
            pred = succ.prev;
        }

        for (Object o : a) {// 雙向鏈表的插入操作
            @SuppressWarnings("unchecked") E e = (E) o;
            Node newNode = new Node<>(pred, e, null);
            if (pred == null)
                first = newNode;
            else
                pred.next = newNode;
            pred = newNode;
        }

        if (succ == null) {//相當于將鏈表后移
            last = pred;
        } else {
            pred.next = succ;
            succ.prev = pred;
        }

        size += numNew;
        modCount++;
        return true;
    }

注意最終調用的是這個 addAll方法,這個方法是在指定位置 index 插入 Collection,使鏈表后面的元素右移,第一個 addAll中傳入的 indexsize,因此就是在結尾添加。

重要方法 add:在鏈尾添加元素
 public boolean add(E e) {
        linkLast(e);
        return true;
    }
 void linkLast(E e) {
        final Node l = last;
        final Node newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }    

除了這個 linkLast方法以外,還提供了 linkFirst linkBefore unLink unLinkFirst等一些方法,都是為實現(xiàn) addremove方法服務的,因為雙向鏈表的原因,這些實現(xiàn)都很簡單。

clear

因為底層實現(xiàn)不是數(shù)組,LinkedList中的 clear方法稍微復雜一些:

public void clear() {
        // Clearing all of the links between nodes is "unnecessary", but:
        // - helps a generational GC if the discarded nodes inhabit
        //   more than one generation
        // - is sure to free memory even if there is a reachable Iterator
        for (Node x = first; x != null; ) {
            Node next = x.next;
            x.item = null;
            x.next = null;
            x.prev = null;
            x = next;
        }
        first = last = null;
        size = 0;
        modCount++;
    }

clear方法中逐一取出每個結點,然后將它們的 item pre next都設為 null,有時候看以來不必要,但是為了防止在GC中,這些結點寄居在不同的年代中,因此最好這么做。

clone

先看 clone方法的實現(xiàn):

public Object clone() {
        LinkedList clone = superClone();

        // Put clone into "virgin" state
        clone.first = clone.last = null;
        clone.size = 0;
        clone.modCount = 0;

        // Initialize clone with our elements
        for (Node x = first; x != null; x = x.next)
            clone.add(x.item);

        return clone;
    }
    
@SuppressWarnings("unchecked")
    private LinkedList superClone() {
        try {
            return (LinkedList) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e);
        }
    }    

可以看到, LinkedListClone方法只是簡單的將原來每個 nodeitem放到克隆后的對象中,和 ArrayListclone方法一樣, LinkedListClone方法也只是淺復制,如果元素為引用類型,那么修改原 list的值會影響克隆的 list的值。

迭代元素

如果仔細觀察,你會發(fā)現(xiàn)在 LinkedList中是沒有自己實現(xiàn) iterator的,如果這樣調用:

LinkedList list = new LinkedList<>();
Iterator it = list.iterator();

你會發(fā)現(xiàn)它調用的是 AbstractSequentialList中的 iterator(),返回的還是 AbstractList 中的 listIterator(),而在 LinkedList中實現(xiàn)了自己的 listIterator,因此如果進行迭代,還是老老實實用 LinkedList中的 listIterator比較好。
LinkedList中還提供了逆序的 Iterator—— DescendingIterator,實際上它也只是簡單的對 ListIterator進行了封裝:

private class DescendingIterator implements Iterator {
        private final ListItr itr = new ListItr(size());
        public boolean hasNext() {
            return itr.hasPrevious();
        }
        public E next() {
            return itr.previous();
        }
        public void remove() {
            itr.remove();
        }
    }

public Iterator descendingIterator() {
        return new DescendingIterator();
    }    
和ArrayList的區(qū)別

這里只是說一下大致的區(qū)別:

ArrayList繼承于 AbstractListLinkedList繼承于 AbstractSequentialList

ArrayList基于數(shù)組, LinkedList基于雙向鏈表,對于隨機訪問, ArrayList比較占優(yōu)勢,對于插入刪除,LinkedList占優(yōu)勢;

LinkedList沒有實現(xiàn)自己的 Iterator,但是有 ListIterator DescendingIterator;

LinkedList需要更多的內存,因為 ArrayList的每個索引的位置是實際的數(shù)據,而 LinkedList中的每個節(jié)點中存儲的是實際的數(shù)據和前后節(jié)點的位置;

ArrayListLinkedList都是非同步的集合。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64471.html

相關文章

  • Java 集合框架淺析

    摘要:是非,而是,這意味著是線程安全的,多個線程可以共享一個而如果沒有正確的同步的話,多個線程是不能共享的。另一個區(qū)別是的迭代器是迭代器,而的迭代器不 這里只解析一些常用的、比較重要的一些集合類,并且作者水平有限,有些地方可能解析不到位或者解析錯誤,還望各位讀者指出錯誤。 Collection List ArrayList LinkedLis...

    LeviDing 評論0 收藏0
  • 數(shù)據結構 - 收藏集 - 掘金

    面試舊敵之紅黑樹(直白介紹深入理解) - Android - 掘金 讀完本文你將了解到: 什么是紅黑樹 黑色高度 紅黑樹的 5 個特性 紅黑樹的左旋右旋 指定節(jié)點 x 的左旋 右圖轉成左圖 指定節(jié)點 y 的右旋左圖轉成右圖 紅黑樹的平衡插入 二叉查找樹的插入 插入后調整紅黑樹結構 調整思想 插入染紅后... java 多線程同步以及線程間通信詳解 & 消費者生產者模式 & 死鎖 & Thread...

    leeon 評論0 收藏0
  • 集合框架源碼學習之LinkedList

    摘要:它們會在鏈表為空時,拋出獲取尾節(jié)點數(shù)據方法兩者區(qū)別方法在鏈表為空時,會拋出,而則不會,只是會返回。 目錄: 0-1. 簡介 0-2. 內部結構分析 0-3. LinkedList源碼分析   0-3-1. 構造方法   0-3-2. 添加add方法     0-3-3. 根據位置取數(shù)據的方法   0-3-4. 根據對象得到索引的方法   0-3-5. 檢查鏈表是否包含某對象的方法  ...

    kumfo 評論0 收藏0
  • LinkedList源碼分析:JDK源碼分析系列

    摘要:介紹是線程不安全的,允許元素為的雙向鏈表。構造方法共有兩個構造方法,一個是創(chuàng)建一個空的構造函數(shù),一個是將已有的添加到中。是將元素插入到的頭部。下一篇文章繼續(xù)分析上次分析了的結構和添加方法這次開始分析下面的。注意源碼版本為直接進入正題。 如果本文中有不正確的地方請指出由于沒有留言可以在公眾號添加我的好友共同討論。 1.介紹 LinkedList 是線程不安全的,允許元素為null的雙向鏈...

    blair 評論0 收藏0
  • LinkedList源碼和并發(fā)問題分析

    摘要:在次操作中其實即尾節(jié)點是共享資源,當多個線程同時執(zhí)行此方法的時候,其實會出現(xiàn)線程安全問題。同樣會出現(xiàn)并發(fā)安全問題,下面對此問題進行分析。 1.LinkedList源碼分析 LinkedList的是基于鏈表實現(xiàn)的java集合類,通過index插入到指定位置的時候使用LinkedList效率要比ArrayList高,以下源碼分析是基于JDK1.8. 1.1 類的繼承結構 LinkedLis...

    xietao3 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<