国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java集合之LinkedList

這篇具有很好參考價(jià)值的文章主要介紹了Java集合之LinkedList。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

基本介紹?

常用方法

源碼解析

1. LinkedList的底層結(jié)構(gòu),Node雙向鏈表

2. LinkedList的幾個(gè)內(nèi)部變量

3.?getFirst()

4.?removeFirst()

5. addFirst(E e)

6.?contains(Object o)

7. add(E e)

8. remove(Object o)

9. addAll(int index, Collection c)

10. get(int index)

11.?spliterator()

總結(jié)


基本介紹?

LinkedList是實(shí)現(xiàn)了List和Deque接口的雙向鏈表,實(shí)現(xiàn)了所有可選列表的操作,允許存放所有元素(包括null)

java linkedlist,# 集合,java,鏈表

LinkedList是非線程安全的,因此在多線程的情況下,需要加同步鎖來(lái)保證線程安全,或者使用Collections.synchronizedList?

常用方法

public LinkedList()
public LinkedList(Collection<? extends E> c)
public E getFirst()  獲取第一個(gè)元素
public E getLast()  獲取最后一個(gè)元素
public boolean add(E e)  添加一個(gè)元素
public void add(int index, E element)  在指定位置插入元素
public void addFirst(E e)  在集合前部增加一個(gè)元素
public void addLast(E e)  在集合尾部增加一個(gè)元素
public boolean addAll(Collection<? extends E> c)  把另一個(gè)集合全部添加到當(dāng)前集合
public boolean addAll(int index, Collection<? extends E> c) 在指定位置把另一個(gè)集合全部添加到當(dāng)前集合
public boolean contains(Object o)  判斷是否包含
public int size()  返回集合大小
public boolean remove(Object o)  根據(jù)指定對(duì)象刪除元素
public E remove(int index)  根據(jù)指定索引刪除元素
public E removeFirst()  刪除第一個(gè)元素
public E removeLast()  刪除最后一個(gè)元素
public E get(int index)  根據(jù)索引獲取元素
public E set(int index, E element)  在指定索引處添加一個(gè)元素(覆蓋原數(shù)據(jù))
public int indexOf(Object o)  返回指定元素索引
public int lastIndexOf(Object o)  返回指定元素出現(xiàn)的最后一個(gè)索引

源碼解析

1. LinkedList的底層結(jié)構(gòu),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;
    }
}

2. LinkedList的幾個(gè)內(nèi)部變量

transient int size = 0;

// 標(biāo)記鏈表第一個(gè)元素
transient Node<E> first;

// 標(biāo)記鏈表最后一個(gè)元素
transient Node<E> last;

// 鏈表結(jié)構(gòu)修改的次數(shù)
protected transient int modCount = 0;

3.?getFirst()

public E getFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return f.item;
}

這個(gè)方法比較簡(jiǎn)單,其實(shí)就是取鏈表的first節(jié)點(diǎn),getLast()方法類似,不再贅述

4.?removeFirst()

public E removeFirst() {
    // 拿到first節(jié)點(diǎn)
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}

private E unlinkFirst(Node<E> f) {
    final E element = f.item;
    final Node<E> next = f.next;
    // 把需要?jiǎng)h除的節(jié)點(diǎn)的值置為空,并且把其引用也置為空
    f.item = null;
    f.next = null; // help GC
    // 把next節(jié)點(diǎn)置為first節(jié)點(diǎn)
    first = next;
    // 如果next節(jié)點(diǎn)為空,說(shuō)明整個(gè)鏈表為空
    if (next == null)
        // 則把last節(jié)點(diǎn)也置為空
        last = null;
    else
        // 把next節(jié)點(diǎn)的前置引用置為空,因?yàn)閜rev節(jié)點(diǎn)已經(jīng)刪除,next節(jié)點(diǎn)已經(jīng)為頭節(jié)點(diǎn)
        // 此時(shí)原來(lái)的first節(jié)點(diǎn)的引用已經(jīng)全部置空,下一次GC時(shí)會(huì)把這個(gè)節(jié)點(diǎn)回收
        next.prev = null;

    // 容器的size - 1
    size--;
    modCount++;
    return element;
}
removceLast()方法類似,只是反過(guò)來(lái)將最后一個(gè)元素置空。

5. addFirst(E e)

public void addFirst(E e) {
    linkFirst(e);
}

private void linkFirst(E e) {
    final Node<E> f = first;
    // 實(shí)例化一個(gè)Node節(jié)點(diǎn),設(shè)置前置節(jié)點(diǎn)為null,原來(lái)的first節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)的next節(jié)點(diǎn)
    final Node<E> newNode = new Node<>(null, e, f);

    // 把鏈表的first節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)
    first = newNode;
    // 如果當(dāng)前鏈表為空
    if (f == null)
        // 則將last節(jié)點(diǎn)也置為新實(shí)例化的節(jié)點(diǎn)
        last = newNode;
    else
        // 否則,將原有的first節(jié)點(diǎn)的前置節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)
        f.prev = newNode;
    size++;
    modCount++;
}

addLast() 也類似,不再詳細(xì)說(shuō)明了

6.?contains(Object o)

public boolean contains(Object o) {
    return indexOf(o) != -1;
}

public int indexOf(Object o) {
    int index = 0;
    // 判斷元素是否為空
    if (o == null) {
        // 循環(huán)找到對(duì)應(yīng)元素,找到第一個(gè)相同元素則返回當(dāng)前索引
        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;
}

7. add(E e)

public boolean add(E e) {
    // 將元素添加到鏈表的最后一位
    linkLast(e);
    return true;
}

void linkLast(E e) {
    final Node<E> l = last;
    // 實(shí)例化一個(gè)Node節(jié)點(diǎn),將原來(lái)的last節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)的前置節(jié)點(diǎn),后置節(jié)點(diǎn)置為null
    final Node<E> newNode = new Node<>(l, e, null);
    // 將last節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)
    last = newNode;
    // 如果原先的last節(jié)點(diǎn)為空,說(shuō)明之前鏈表為空
    if (l == null)
        // 將first節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)
        first = newNode;
    else
        // 否則將之前l(fā)ast節(jié)點(diǎn)的next節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)
        l.next = newNode;
    size++;
    modCount++;
}

8. remove(Object o)

public boolean remove(Object o) {
    // 跟其他方法很類似,先判斷元素是否為null
    if (o == null) {
        // 循環(huán)找到對(duì)應(yīng)元素,并執(zhí)行unlink方法
        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;
}


E unlink(Node<E> x) {
    final E element = x.item;
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;
    
    // 如果前置節(jié)點(diǎn)為空,說(shuō)明當(dāng)前待刪除節(jié)點(diǎn)是頭節(jié)點(diǎn)
    if (prev == null) {
        // 把first節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)的next節(jié)點(diǎn)
        first = next;
    } else {
        // 否則就把當(dāng)前節(jié)點(diǎn)的前置節(jié)點(diǎn)的next節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)的next節(jié)點(diǎn)
        prev.next = next;
        // 把待刪除節(jié)點(diǎn)的前置節(jié)點(diǎn)置為null
        x.prev = null;
    }

    // 如果待刪除節(jié)點(diǎn)的next節(jié)點(diǎn)為null,說(shuō)明當(dāng)前節(jié)點(diǎn)是最后一個(gè)節(jié)點(diǎn)
    if (next == null) {
        // 將當(dāng)前鏈表的last節(jié)點(diǎn)置為待刪除節(jié)點(diǎn)的前置節(jié)點(diǎn)
        last = prev;
    } else {
        // 把當(dāng)前節(jié)點(diǎn)的next節(jié)點(diǎn)的前置節(jié)點(diǎn)置為當(dāng)前節(jié)點(diǎn)的前置節(jié)點(diǎn)
        next.prev = prev;
        // 當(dāng)前節(jié)點(diǎn)的next節(jié)點(diǎn)置為null
        // 此時(shí)待刪除節(jié)點(diǎn)的引用關(guān)系已經(jīng)全部置空
        x.next = null;
    }
    // 把當(dāng)前節(jié)點(diǎn)的數(shù)據(jù)置為null
    x.item = null;
    size--;
    modCount++;
    return element;
}

9. addAll(int index, Collection<? extends E> c)

/**
 * 在索引位置插入新的集合
 *
 * @Param index 索引
 * @Param c 需要添加的集合
 */
public boolean addAll(int index, Collection<? extends E> c) {
    // 校驗(yàn)index是否超出范圍
    checkPositionIndex(index);

    // 將集合轉(zhuǎn)成數(shù)組
    Object[] a = c.toArray();
    int numNew = a.length;

    // 如果需要添加的集合為空,直接return false
    if (numNew == 0)
        return false;

    Node<E> pred, succ;

    // 如果索引位置等于當(dāng)前集合的size,說(shuō)明要將新的集合添加在鏈表的尾部
    if (index == size) {
        succ = null;
        pred = last;
    } else {
        // 把當(dāng)前索引的元素賦值給succ
        succ = node(index);
        // 當(dāng)前索引的前置節(jié)點(diǎn)賦值給pred
        pred = succ.prev;
    }

    // 循環(huán)數(shù)組
    for (Object o : a) {
        Node<E> newNode = new Node<>(pred, e, null);
        // 如果pred為null,則將新node對(duì)象賦值給first
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        // 把pred置為當(dāng)前元素,繼續(xù)添加下一個(gè)元素
        pred = newNode;
    }
    
    // 如果是在隊(duì)尾添加元素
    if (succ == null) {
        // 則將鏈表的last節(jié)點(diǎn)置為pred,因?yàn)樯厦嬖谘h(huán)末尾會(huì)將pred = newNode,此時(shí)pred就是最后一個(gè)元素
        last = pred;
    } else {
        pred.next = succ;
        succ.prev = pred;
    }

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

private void checkPositionIndex(int index) {
    if (!isPositionIndex(index))
        // 如果超出范圍就拋出IndexOutOfBoundsException
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

private boolean isPositionIndex(int index) {
    return index >= 0 && index <= size;
}

10. get(int index)

public E get(int index) {
    // 校驗(yàn)索引是否越界,如果越界則拋異常
    checkElementIndex(index);
    // 返回當(dāng)前節(jié)點(diǎn)的元素
    return node(index).item;
}

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

private boolean isElementIndex(int index) {
    return index >= 0 && index < size;
}

Node<E> node(int index) {
    // 判斷索引是靠近前半部分還是后半部分
    if (index < (size >> 1)) {
        // 如果索引靠前,則從頭開(kāi)始遍歷,直到當(dāng)前索引
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        // 然后返回當(dāng)前索引對(duì)應(yīng)的node
        return x;
    } else {
        Node<E> x = last;
        // 如果索引靠后,則從末尾開(kāi)始向前遍歷
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

11.?spliterator()

LinkedList中還有spliterator拆分器,該拆分器是后期綁定的,并且使用與鏈接列表相同的元素快速失效。后期綁定拆分器綁定到元素源意味著在第一次遍歷、第一次拆分或第一次查詢估計(jì)大小時(shí)鏈接列表,而不是在創(chuàng)建拆分器時(shí)。它可以和 Java 8 中的 Streams 一起使用。此外,它還可以單獨(dú)和批量遍歷元素。Spliterator 是遍歷元素的更好方法,因?yàn)樗鼘?duì)元素提供了更多的控制。

這個(gè)拆分器感覺(jué)在我平時(shí)的工作中用的也不多,就不做解析了,如果大家想看看這個(gè)方法的解析的話給我留言,我再單獨(dú)寫(xiě)一篇這個(gè)的解析。

總結(jié)

1. LinkedList底層是由雙向鏈表實(shí)現(xiàn)的

2. LinkedList插入和刪除比較快,因?yàn)檎2迦攵际遣迦腈湵淼淖詈笠粋€(gè)元素,只需要改變前置節(jié)點(diǎn)的next指向和當(dāng)前節(jié)點(diǎn)的前置指向即可,不需要想ArrayList一樣移動(dòng)數(shù)組

3. LinkedList如果按照索引查詢會(huì)很慢,因?yàn)樗枰獜念^或從尾開(kāi)始逐個(gè)遍歷直到對(duì)應(yīng)索引位置,不支持隨機(jī)訪問(wèn)

4. LinkedList是非線程安全的

5.?LinkedList元素允許為null,允許重復(fù)元素

6.?LinkedList是基于雙向鏈表實(shí)現(xiàn)的,所以不存在容量不足的情況,不需要擴(kuò)容文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-608155.html

到了這里,關(guān)于Java集合之LinkedList的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • java源碼----集合系列1----ArrayList,linkedList

    java源碼----集合系列1----ArrayList,linkedList

    底層是一個(gè)object數(shù)組 Arraylist 是java里面Collection? 標(biāo)準(zhǔn)的一個(gè)集合,其 底層是一個(gè)object數(shù)組 。當(dāng)new一個(gè)空參的ArrayList的時(shí)候,會(huì)默認(rèn)生成一個(gè)空數(shù)組。 Arraylist上限是 Integer.MAX_VALUE - 8(Integer.MAX_VALUE? = ?2^31-1) ; 超過(guò)上限會(huì)報(bào)內(nèi)存溢出 這里為什么是Integer.MAX_VALUE-8? ,源碼上的解

    2024年02月03日
    瀏覽(28)
  • Java集合篇之深入解析LinkedList

    Java集合篇之深入解析LinkedList

    作為ArrayList的同門師兄弟,LinkedList的師門地位遜色不少,除了在做算法題的時(shí)候我們會(huì)用到它之外,在實(shí)際的開(kāi)發(fā)工作中我們極少使用它,就連它的創(chuàng)造者都說(shuō):“I wrote it,and I never use it”,想想頗有點(diǎn)好笑,但這并不影響我們?nèi)W(xué)習(xí)它,個(gè)人認(rèn)為它底層的鏈表邏輯對(duì)于我

    2024年02月19日
    瀏覽(24)
  • Java基礎(chǔ)——LinkedList集合實(shí)現(xiàn)棧和隊(duì)列

    (1)LinkedList的特點(diǎn): 底層數(shù)據(jù)結(jié)構(gòu)是雙鏈表,查詢慢,首尾操作的速度是極快的,所以多了很多首位操作的特有API。 (2)LinkedList集合的特有功能: 方法名稱 說(shuō)明 public void addFirst(E e) 在該列表開(kāi)頭插入指定的元素 public void addLast(E e) 將指定的元素追加到此列表的末尾 publ

    2023年04月12日
    瀏覽(16)
  • java集合框架(二)LinkedList常見(jiàn)方法的使用

    @[toc] ## 一、什么是LinkedList LinkedList是Java中的一個(gè)雙向鏈表。 它實(shí)現(xiàn)了List和Deque接口,在使用時(shí)可以像List一樣使用元素索引,也可以像Deque一樣使用隊(duì)列操作。 LinkedList每個(gè)節(jié)點(diǎn)都包含了前一個(gè)和后一個(gè)節(jié)點(diǎn)的引用,因此可以很方便地在其中進(jìn)行節(jié)點(diǎn)的插入、刪除和移動(dòng)。 相

    2024年02月05日
    瀏覽(22)
  • 【Java集合進(jìn)階】Collection 體系集合詳解(ArrayList,LinkedList,HashSet,TreeSet...)
  • Java語(yǔ)言----LinkedList 和 鏈表的實(shí)現(xiàn)

    Java語(yǔ)言----LinkedList 和 鏈表的實(shí)現(xiàn)

    目錄 一.鏈表概念 二.鏈表的分類? 三.無(wú)頭單向非循環(huán)鏈表的實(shí)現(xiàn) 3.1創(chuàng)建簡(jiǎn)單鏈表 3.2 鏈表基本方法實(shí)現(xiàn) 3.3四大基本功能 ? ? ? ? ? ???3.3.1.增加元素結(jié)點(diǎn) ? ? ? ? ? ? ?3.3.2.查找元素結(jié)點(diǎn) ? ? ? ? ? ? ?3.3.3.刪除元素結(jié)點(diǎn) ? ? ? ? ? ? ?3.3.4.結(jié)點(diǎn)信息修改 ? 四.LinkedList是什

    2024年02月02日
    瀏覽(28)
  • 【JAVA語(yǔ)言-第15話】集合框架(二)——List、ArrayList、LinkedList、Vector集合

    【JAVA語(yǔ)言-第15話】集合框架(二)——List、ArrayList、LinkedList、Vector集合

    目錄 List集合 1.1?概述 1.2 特點(diǎn) 1.3 常用方法 1.4?ArrayList集合 1.4.1 概述? 1.4.2 練習(xí) 1.5 LinkedList集合? 1.5.1 概述 1.5.2 特點(diǎn) 1.5.3 常用方法 1.5.4 練習(xí) 1.6?Vector類 1.6.1 概述 1.6.2 練習(xí) 1.7 List實(shí)現(xiàn)類的異同點(diǎn) ????????java.util.List: List是一個(gè)接口,它繼承自Collection接口。 常用的實(shí)現(xiàn)

    2024年01月25日
    瀏覽(22)
  • 數(shù)據(jù)結(jié)構(gòu)(Java實(shí)現(xiàn))LinkedList與鏈表(上)

    數(shù)據(jù)結(jié)構(gòu)(Java實(shí)現(xiàn))LinkedList與鏈表(上)

    鏈表 邏輯結(jié)構(gòu) 無(wú)頭單向非循環(huán)鏈表:結(jié)構(gòu)簡(jiǎn)單,一般不會(huì)單獨(dú)用來(lái)存數(shù)據(jù)。實(shí)際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu),如哈希桶、圖的鄰接表等等。 無(wú)頭雙向鏈表:在Java的集合框架庫(kù)中LinkedList底層實(shí)現(xiàn)就是無(wú)頭雙向循環(huán)鏈表。 鏈表的實(shí)現(xiàn) 創(chuàng)建一個(gè)鏈表 遍歷單鏈表 、 得到

    2024年02月11日
    瀏覽(30)
  • 數(shù)據(jù)結(jié)構(gòu)(Java實(shí)現(xiàn))LinkedList與鏈表(下)

    數(shù)據(jù)結(jié)構(gòu)(Java實(shí)現(xiàn))LinkedList與鏈表(下)

    ** ** 結(jié)論 讓一個(gè)指針從鏈表起始位置開(kāi)始遍歷鏈表,同時(shí)讓一個(gè)指針從判環(huán)時(shí)相遇點(diǎn)的位置開(kāi)始繞環(huán)運(yùn)行,兩個(gè)指針都是每次均走一步,最終肯定會(huì)在入口點(diǎn)的位置相遇。 LinkedList的模擬實(shí)現(xiàn) 單個(gè)節(jié)點(diǎn)的實(shí)現(xiàn) 尾插 運(yùn)行結(jié)果如下: 也可以暴力使用 全部代碼 MyLinkedList IndexOut

    2024年02月11日
    瀏覽(22)
  • 【JAVA學(xué)習(xí)筆記】53 - 集合-List類及其子類Collection、ArrayList、LinkedList類

    【JAVA學(xué)習(xí)筆記】53 - 集合-List類及其子類Collection、ArrayList、LinkedList類

    https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter14/src/com/yinhai/collection_ https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter14/src/com/yinhai/list_ 目錄 項(xiàng)目代碼 集合 一、引入 數(shù)組 集合 二、集合的框架體系 單列集合? ? ? ? 雙列集合? ? ? ? Collection類 一、Collection類接

    2024年02月06日
    瀏覽(31)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包