8.LinkedList

ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。
LinkedList不支持高效的隨機(jī)元素訪問慧耍。
ArrayList的空間浪費(fèi)主要體現(xiàn)在在list列表的結(jié)尾預(yù)留一定的容量空間,而LinkedList的空間花費(fèi)則體現(xiàn)在它的每一個(gè)元素都需要消耗相當(dāng)?shù)目臻g,就存儲(chǔ)密度來說昌腰,ArrayList是優(yōu)于LinkedList的。

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
   //實(shí)現(xiàn)Serilizable接口時(shí)膀跌,將不需要序列化的屬性前添加關(guān)鍵字transient遭商,序列化對(duì)象的時(shí)候,這個(gè)屬性就不會(huì)序列化到指定的目的地中捅伤。
    transient int size = 0;
    //指向首節(jié)點(diǎn)
    transient Node<E> first;
    //指向最后一個(gè)節(jié)點(diǎn)
    transient Node<E> last;
    //構(gòu)建一個(gè)空列表
    public LinkedList() {
    }
    //構(gòu)建一個(gè)包含集合c的列表
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }
   //將節(jié)點(diǎn)值為e的節(jié)點(diǎn)作為首節(jié)點(diǎn)
    private void linkFirst(E e) {
        final Node<E> f = first;
        //構(gòu)建一個(gè)prev值為null,next為f,節(jié)點(diǎn)值為e的節(jié)點(diǎn)
        final Node<E> newNode = new Node<>(null, e, f);
        //將newNode作為首節(jié)點(diǎn)
        first = newNode;
        //如果newNode后面沒有節(jié)點(diǎn)就將newNode作為最后一個(gè)節(jié)點(diǎn)
        if (f == null)
            last = newNode;
        //否則就將newNode賦給其prev
        else
            f.prev = newNode;
        //列表長度加一
        size++;
        modCount++;
    }
    //將節(jié)點(diǎn)值為e的節(jié)點(diǎn)作為最后一個(gè)節(jié)點(diǎn)
    void linkLast(E e) {
        final Node<E> l = last;
      //構(gòu)建一個(gè)prev值為l,next為null,節(jié)點(diǎn)值為e的節(jié)點(diǎn)
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
    //在非空節(jié)點(diǎn)succ之前插入節(jié)點(diǎn)e
    void linkBefore(E e, Node<E> succ) {
        final Node<E> pred = succ.prev;
        //將succ前面的節(jié)點(diǎn)和succ作為其prev和next
        final Node<E> newNode = new Node<>(pred, e, succ);
        //然后將newNode作為succ的prev
        succ.prev = newNode; 
        //如果原來succ是首節(jié)點(diǎn)劫流,則將newNode設(shè)置為首節(jié)點(diǎn)
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }
     //釋放非空的首節(jié)點(diǎn)f
    private E unlinkFirst(Node<E> f) {
        final E element = f.item;
        final Node<E> next = f.next;
        f.item = null;
        f.next = null; // help GC
        //將first節(jié)點(diǎn)后面的節(jié)點(diǎn)設(shè)為首節(jié)點(diǎn)
        first = next;
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        modCount++;
        return element;
    }
     //釋放非空的尾節(jié)點(diǎn)l
       private E unlinkLast(Node<E> l) {
        final E element = l.item;
        final Node<E> prev = l.prev;
        l.item = null;
        l.prev = null; // help GC
        last = prev;
        if (prev == null)
            first = null;
        else
            prev.next = null;
        size--;
        modCount++;
        return element;
    }
    //刪除非空節(jié)點(diǎn)x
    E unlink(Node<E> x) 
    {
        final E element = x.item;
        final Node<E> next = x.next;    //x后面的節(jié)點(diǎn)
        final Node<E> prev = x.prev;    //x前面的節(jié)點(diǎn)

        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }
        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }
        x.item = null;
        size--;
        modCount++;
        return element;
    }
    //返回列表首節(jié)點(diǎn)元素值
    public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }
    //返列表尾節(jié)點(diǎn)元素值
    public E getLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
    }
    //移除首節(jié)點(diǎn)
    public E removeFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
    }
   //刪除尾節(jié)點(diǎn)
    public E removeLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
    }
  //在列表首部插入節(jié)點(diǎn)e
    public void addFirst(E e) {
        linkFirst(e);
    }
    //在列表尾部插入節(jié)點(diǎn)e
    public void addLast(E e) {
        linkLast(e);
    }
   //判斷列表中是否包含有元素o
    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }
    //返回列表長度大小
    public int size() {
        return size;
    }
    //在列表尾部插入元素
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    //刪除元素為o的節(jié)點(diǎn)
    public boolean remove(Object o) 
    {    
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }
   //將集合c中所有元素添加到列表的尾部
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }
   //從指定的位置index開始,將集合c中的元素插入到列表中
    public boolean addAll(int index, Collection<? extends E> c) {
        //首先判斷插入位置的合法性
        checkPositionIndex(index);
        Object[] a = c.toArray();
        int numNew = a.length;
        if (numNew == 0)
            return false;
        Node<E> pred, succ;
        if (index == size) {//說明在列表尾部插入集合元素
            succ = null;
            pred = last;
        } 
        else {  //否則丛忆,找到index所在的節(jié)點(diǎn)
            succ = node(index);
            pred = succ.prev;
        }
        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
            Node<E> 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;
    }
    //刪除列表中所有節(jié)點(diǎn)
    public void clear() {
        for (Node<E> x = first; x != null; )  
        {
            Node<E> next = x.next;
            x.item = null;
            x.next = null;
            x.prev = null;
            x = next;
        }
        first = last = null;
        size = 0;
        modCount++;
    }
    //獲取指定索引位置節(jié)點(diǎn)的元素值
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
    //替換指定索引位置節(jié)點(diǎn)的元素值
    public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
    }
    //在指定索引位置之前插入元素e
    public void add(int index, E element) {
        checkPositionIndex(index);   
        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
    //刪除指定位置的元素
    public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }
    //判斷指定索引位置的元素是否存在
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }
    private boolean isPositionIndex(int index) {
        return index >= 0 && index <= size;
    }
    //構(gòu)建 IndexOutOfBoundsException詳細(xì)信息
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }
    private void checkElementIndex(int index) {
        if (!isElementIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    //返回指定索引位置的節(jié)點(diǎn)
    Node<E> node(int index) {
        //此處是一個(gè)小技巧祠汇,當(dāng)index<size/2時(shí),從列表前半部分開始熄诡,否則從后半部分開始
        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;
        }
    }//返回列表中第一次出現(xiàn)o的位置座哩,若不存在則返回-1
    public int indexOf(Object o) {
        int index = 0;
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
    }
    //逆向搜索,返回第一出現(xiàn)o的位置粮彤,不存在則返回-1
    public int lastIndexOf(Object o) {
        int index = size;
        if (o == null) {
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (x.item == null)
                    return index;
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (o.equals(x.item))
                    return index;
            }
        }
        return -1;
    }
   //獲取列表首節(jié)點(diǎn)元素值
    public E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
    }

    //獲取列表首節(jié)點(diǎn)元素值根穷,若為空則拋異常
    public E element() {
        return getFirst();
    }
   //檢索首節(jié)點(diǎn),若空則返回null,不為空則返回其元素值并刪除首節(jié)點(diǎn)
    public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }
    //檢索首節(jié)點(diǎn)导坟,若空則拋異常,不為空則返回其元素值并刪除首節(jié)點(diǎn)
    public E remove() {
        return removeFirst();
    }
   //在列表尾部增加節(jié)點(diǎn)e
    public boolean offer(E e) {
        return add(e);
    }
   //在列表首部插入節(jié)點(diǎn)e
    public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }
  //在列表尾部插入節(jié)點(diǎn)e
    public boolean offerLast(E e) {
        addLast(e);
        return true;
    }
    public E peekFirst() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
     }
  //獲取列表尾節(jié)點(diǎn)元素值
    public E peekLast() {
        final Node<E> l = last;
        return (l == null) ? null : l.item;
    }
    public E pollFirst() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }
    public E pollLast() {
        final Node<E> l = last;
        return (l == null) ? null : unlinkLast(l);
    }
   //入棧
    public void push(E e)
    {
        addFirst(e);
    }
    //出棧
    public E pop() {
        return removeFirst();
    }
    //刪除列表中第一出現(xiàn)o的節(jié)點(diǎn)
    public boolean removeFirstOccurrence(Object o) {
        return remove(o);
    }
    //逆向搜索屿良,刪除第一次出現(xiàn)o的節(jié)點(diǎn)
    public boolean removeLastOccurrence(Object o) {
        if (o == null) {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市惫周,隨后出現(xiàn)的幾起案子尘惧,更是在濱河造成了極大的恐慌,老刑警劉巖递递,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喷橙,死亡現(xiàn)場離奇詭異,居然都是意外死亡登舞,警方通過查閱死者的電腦和手機(jī)贰逾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來菠秒,“玉大人疙剑,你說我怎么就攤上這事。” “怎么了言缤?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵嚼蚀,是天一觀的道長。 經(jīng)常有香客問我管挟,道長轿曙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任僻孝,我火速辦了婚禮导帝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘皮璧。我一直安慰自己舟扎,他們只是感情好分飞,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布悴务。 她就那樣靜靜地躺著,像睡著了一般譬猫。 火紅的嫁衣襯著肌膚如雪讯檐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天染服,我揣著相機(jī)與錄音别洪,去河邊找鬼。 笑死柳刮,一個(gè)胖子當(dāng)著我的面吹牛挖垛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秉颗,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼痢毒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蚕甥?” 一聲冷哼從身側(cè)響起哪替,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎菇怀,沒想到半個(gè)月后凭舶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爱沟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年帅霜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呼伸。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡义屏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闽铐,我是刑警寧澤蝶怔,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站兄墅,受9級(jí)特大地震影響踢星,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隙咸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一沐悦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧五督,春花似錦藏否、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至基矮,卻和暖如春淆储,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背家浇。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工本砰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钢悲。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓点额,卻偏偏與公主長得像,于是被迫代替她去往敵國和親莺琳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子还棱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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