淺析LinkedList

寫(xiě)在前面

本文所看的源碼是在idea里面查看的互婿,一些代碼和Java的源碼可能有所不同……但是思想應(yīng)該是一致的鹏控。
上一篇淺析ArrayList簡(jiǎn)要的了解了一下ArrayList是如何實(shí)現(xiàn)的,ArrayList內(nèi)部是用一個(gè)Object數(shù)組對(duì)象來(lái)作為容器盛放各個(gè)對(duì)象的蠕啄。而LinkedList則不然筑悴,其內(nèi)部實(shí)現(xiàn)就類(lèi)似于數(shù)據(jù)結(jié)構(gòu)中的雙向鏈表。只不過(guò)在Java中可能你不能直接使用“指針”沼死,所以得通過(guò)Java的“引用”來(lái)實(shí)現(xiàn)這個(gè)雙向鏈表。那么今天也讓我們通過(guò)幾個(gè)比較經(jīng)典的方法來(lái)看一下其內(nèi)部實(shí)現(xiàn)崔赌。

Node

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

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

很經(jīng)典的一個(gè)數(shù)據(jù)結(jié)構(gòu)……(笑)
考慮到了代碼的兼容性加入了泛型意蛀,這些都是可以暫時(shí)不看的耸别,對(duì)我們了解其實(shí)現(xiàn)沒(méi)什么大的影響。

這個(gè)類(lèi)內(nèi)部一個(gè)next一個(gè)prev分別代表了當(dāng)前節(jié)點(diǎn)的前驅(qū)和后繼县钥,大白話(huà)就是這節(jié)點(diǎn)的前一個(gè)元素和后一個(gè)元素秀姐,item是保存的值。

add()

    /**
     * Appends the specified element to the end of this list.
     *
     * <p>This method is equivalent to {@link #addLast}.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

向鏈表的尾部插入一個(gè)值若贮,那么繼續(xù)看看linkLast(e)是怎么實(shí)現(xiàn)的

    /**
     * Links e as last element.
     */
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

可以看出這個(gè)方法會(huì)將節(jié)點(diǎn)插入鏈表的尾部省有。在LinkedList內(nèi)部有一個(gè)指向尾部的引用,所以插入尾部實(shí)現(xiàn)起來(lái)十分簡(jiǎn)單谴麦。先將尾節(jié)點(diǎn)引用指向新節(jié)點(diǎn)蠢沿,之后判斷一下頭節(jié)點(diǎn)是否為空,如果是空的話(huà)匾效,那么說(shuō)明這個(gè)鏈表還沒(méi)有節(jié)點(diǎn)舷蟀,那么將第一個(gè)節(jié)點(diǎn)的引用指向這個(gè)節(jié)點(diǎn),如果非空的話(huà)就將新的節(jié)點(diǎn)插入到最后一個(gè)節(jié)點(diǎn)的后面面哼。

get()

    /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }

這個(gè)方法會(huì)返回一個(gè)特定位置的node所存儲(chǔ)的值野宜。代碼很少一共就兩行,先看第一行的代碼是個(gè)啥:

    private void checkElementIndex(int index) {
        if (!isElementIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    /**
     * Tells if the argument is the index of an existing element.
     */
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }

通過(guò)兩個(gè)方法我們可以看出這個(gè)方法會(huì)檢查你所給的index是否在這個(gè)鏈表內(nèi)魔策,如果不是會(huì)拋出索引越界的異常速缨。

接下來(lái)看看第二行代碼是如何實(shí)現(xiàn)的:

    /**
     * Returns the (non-null) Node at the specified element index.
     */
    Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

可以看出這個(gè)方法還是對(duì)這個(gè)索引進(jìn)行了簡(jiǎn)單的計(jì)算,如果這個(gè)索引大于鏈表的尺寸的一半那么他會(huì)從尾部開(kāi)始遍歷直到找到這個(gè)index對(duì)應(yīng)的node代乃。反之他會(huì)從這個(gè)鏈表的頭部開(kāi)始遍歷旬牲。畢竟雙向鏈表,從哪都行~

暫時(shí)只寫(xiě)這么多吧搁吓,準(zhǔn)備周末再去看下集合框架中的那幾個(gè)接口原茅,回頭來(lái)再詳細(xì)的看一些東西。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末堕仔,一起剝皮案震驚了整個(gè)濱河市擂橘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摩骨,老刑警劉巖通贞,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異恼五,居然都是意外死亡昌罩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)灾馒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)茎用,“玉大人,你說(shuō)我怎么就攤上這事」旃Γ” “怎么了旭斥?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)古涧。 經(jīng)常有香客問(wèn)我垂券,道長(zhǎng),這世上最難降的妖魔是什么羡滑? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任圆米,我火速辦了婚禮,結(jié)果婚禮上啄栓,老公的妹妹穿的比我還像新娘。我一直安慰自己也祠,他們只是感情好昙楚,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著诈嘿,像睡著了一般堪旧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奖亚,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天淳梦,我揣著相機(jī)與錄音,去河邊找鬼昔字。 笑死爆袍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的作郭。 我是一名探鬼主播陨囊,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼夹攒!你這毒婦竟也來(lái)了蜘醋?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤咏尝,失蹤者是張志新(化名)和其女友劉穎压语,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體编检,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胎食,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了允懂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斥季。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酣倾,到底是詐尸還是另有隱情舵揭,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布躁锡,位于F島的核電站午绳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏映之。R本人自食惡果不足惜拦焚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杠输。 院中可真熱鬧赎败,春花似錦、人聲如沸蠢甲。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鹦牛。三九已至搞糕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曼追,已是汗流浹背窍仰。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留礼殊,地道東北人驹吮。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像晶伦,于是被迫代替她去往敵國(guó)和親钥屈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容