【Java集合源碼剖析1.2】LinkedList源碼剖析(API23)

首先LinkedList也是非線程安全的,與ArrayList不同的是內(nèi)部實現(xiàn)方式不同紧索, 所以袁辈,兩者在不同的情況下, 效率也可能不同珠漂。本文參考了(http://www.cnblogs.com/xrq730/p/5005347.html)吵瞻。

LinkedList既然是一種雙向鏈表,必然有一個存儲單元甘磨,看一下LinkedList的基本存儲單元橡羞,它是LinkedList中的一個內(nèi)部類:

   private static final class Link<ET> {
        ET data;        // 真正的數(shù)據(jù)

        Link<ET> previous;      //前一數(shù)據(jù)的引用地址

        Link<ET> next;          //后一數(shù)據(jù)的引用地址

        Link(ET o, Link<ET> p, Link<ET> n) {
            data = o;
            previous = p;
            next = n;
        }
    }

LinkedList構(gòu)造函數(shù)。

  public LinkedList(Collection<? extends E> collection) {
        this();
        addAll(collection);
    }

    public LinkedList() {
        voidLink = new Link<E>(null, null, null);   // 創(chuàng)建空鏈表頭济舆。卿泽。
        voidLink.previous = voidLink;
        voidLink.next = voidLink;
    }

add數(shù)據(jù)時

   @Override
    public boolean add(E object) {
        return addLastImpl(object);
    }

    private boolean addLastImpl(E object) {
        Link<E> oldLast = voidLink.previous;        //  空表頭的前一數(shù)據(jù)地址,其實就是最后一個數(shù)據(jù)的地址滋觉。
        Link<E> newLink = new Link<E>(object, oldLast(前), voidLink(后));   // 新Link的后一個數(shù)據(jù)地址永遠為空表頭的地址签夭。
        voidLink.previous = newLink;          // 重置空表頭的前一數(shù)據(jù)地址為最后添加的數(shù)據(jù)地址。 
        oldLast.next = newLink;     
        size++;
        modCount++;
        return true;
    }

add指定位置數(shù)據(jù)時

@Override
  public void add(int location, E object) {
      if (location >= 0 && location <= size) {
          Link<E> link = voidLink;
          if (location < (size / 2)) {    // 如果為數(shù)據(jù)List的前半部分椎侠。 
              for (int i = 0; i <= location; i++) {    
                  link = link.next;       //找到第 i 個數(shù)據(jù)的下一個數(shù)據(jù) 第租。 
              }
          } else {
              for (int i = size; i > location; i--) {
                  link = link.previous;
              }
          }
          Link<E> previous = link.previous;
          Link<E> newLink = new Link<E>(object, previous, link);
          previous.next = newLink;
          link.previous = newLink;
          size++;
          modCount++;
      } else {
          throw new IndexOutOfBoundsException();
      }
  }

引用例子(原文 :http://www.cnblogs.com/xrq730/p/5005347.html)

public static void main(String[] args)
{
    1  List<String> list = new LinkedList<String>();
    2  list.add("111");
    3  list.add("222");
 }

假設構(gòu)造函數(shù)里new Link() 的地址為0x0000000,那么它的前后地址都為本身地址我纪。

執(zhí)行到代碼1
執(zhí)行到代碼2
執(zhí)行到代碼3

結(jié)合 add()方法慎宾,相信你可以搞懂它們之間的地址賦值。
其它方法大家可自行分析吧浅悉。

小結(jié)():

切勿用普通for循環(huán)遍歷LinkedList
1趟据、順序插入速度ArrayList會比較快术健,因為ArrayList是基于數(shù)組實現(xiàn)的,數(shù)組是事先new好的咳促,只要往指定位置塞一個數(shù)據(jù)就好了勘伺;LinkedList則不同,每次順序插入的時候LinkedList將new一個對象出來尺迂,如果對象比較大,那么new的時間勢必會長一點蹲盘,再加上一些引用賦值的操作膳音,所以順序插入LinkedList必然慢于ArrayList

2、基于上一點苍凛,因為LinkedList里面不僅維護了待插入的元素兵志,還維護了Entry的前置Entry和后繼Entry想罕,如果一個LinkedList中的Entry非常多,那么LinkedList將比ArrayList更耗費一些內(nèi)存

3惭适、數(shù)據(jù)遍歷的速度楼镐,看最后一部分,這里就不細講了凄杯,結(jié)論是:使用各自遍歷效率最高的方式茅信,ArrayList的遍歷效率會比LinkedList的遍歷效率高一些

4、有些說法認為LinkedList做插入和刪除更快,這種說法其實是不準確的:

(1)LinkedList做插入酌摇、刪除的時候,慢在尋址窑多,快在只需要改變前后Entry的引用地址

(2)ArrayList做插入洼滚、刪除的時候,慢在數(shù)組元素的批量copy千康,快在尋址

所以,如果待插入值桩、刪除的元素是在數(shù)據(jù)結(jié)構(gòu)的前半段尤其是非潮挤兀靠前的位置的時候搭盾,LinkedList的效率將大大快過ArrayList,因為ArrayList將批量copy大量的元素鸯隅;越往后滋迈,對于LinkedList來說,因為它是雙向鏈表幕侠,所以在第2個元素后面插入一個數(shù)據(jù)和在倒數(shù)第2個元素后面插入一個元素在效率上基本沒有差別碍彭,但是ArrayList由于要批量copy的元素越來越少,操作速度必然追上乃至超過LinkedList舞箍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疏橄,一起剝皮案震驚了整個濱河市捎迫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌窄绒,老刑警劉巖彰导,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異山析,居然都是意外死亡倔幼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門翩腐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茂卦,“玉大人等龙,你說我怎么就攤上這事≈肱椋” “怎么了泥畅?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵琅翻,是天一觀的道長。 經(jīng)常有香客問我聂抢,道長琳疏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任轿亮,我火速辦了婚禮,結(jié)果婚禮上按咒,老公的妹妹穿的比我還像新娘但骨。我一直安慰自己智袭,他們只是感情好吼野,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布瞳步。 她就那樣靜靜地躺著,像睡著了一般抱怔。 火紅的嫁衣襯著肌膚如雪丛楚。 梳的紋絲不亂的頭發(fā)上寺庄,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天份帐,我揣著相機與錄音尺栖,去河邊找鬼碳胳。 笑死固逗,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的惜傲。 我是一名探鬼主播贝攒,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼隘弊,長吁一口氣:“原來是場噩夢啊……” “哼梨熙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起邪财,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎糠馆,沒想到半個月后怎憋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡毕匀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年期揪,在試婚紗的時候發(fā)現(xiàn)自己被綠了规个。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诞仓。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡墅拭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出舒憾,到底是詐尸還是另有隱情镀迂,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站妓柜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏藏雏。R本人自食惡果不足惜作煌,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧努酸,春花似錦获诈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽于购。三九已至知染,卻和暖如春控淡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辫诅。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勋篓,地道東北人吧享。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像譬嚣,于是被迫代替她去往敵國和親钢颂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

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