成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

LinkedList源碼解析

ShowerSun / 3034人閱讀

摘要:說明是對(duì)鏈表的擴(kuò)展,其底層使用鏈表實(shí)現(xiàn),不是線程安全的集合類。其繼承,實(shí)現(xiàn)了各個(gè)接口,其中繼承了抽象類,是對(duì)支持隨機(jī)讀取的的部分功能的抽象,是對(duì)不支持隨機(jī)讀取的的一部分功能的抽象。并且實(shí)現(xiàn)了接口,代表其支持雙端隊(duì)列的所有功能。

1.說明

LinkedList是對(duì)鏈表的擴(kuò)展,其底層使用鏈表實(shí)現(xiàn),不是線程安全的集合類。其繼承AbstractSequentialList,實(shí)現(xiàn)了List, Deque, Cloneable,Serializable各個(gè)接口,其中AbstractSequentialList繼承了AbstractList抽象類,AbstractList是對(duì)支持隨機(jī)讀取的List的部分功能的抽象,AbstractSequentialList是對(duì)不支持隨機(jī)讀取的List的一部分功能的抽象。并且LinkedList實(shí)現(xiàn)了Deque接口,代表其支持雙端隊(duì)列的所有功能。

2.優(yōu)缺點(diǎn)

LinkedList首先是鏈表的擴(kuò)展,并且實(shí)現(xiàn)了雙端隊(duì)列的接口,所以其特點(diǎn)如下:

隨機(jī)存儲(chǔ),優(yōu)點(diǎn)是不需要提前申請(qǐng)空間

具有雙端隊(duì)列的所有功能,可以簡(jiǎn)單地實(shí)現(xiàn)先進(jìn)先出和后進(jìn)先出

新增和刪除時(shí)間復(fù)雜度比較少

3.重要變量
//元素的個(gè)數(shù)
transient int size = 0;

//首節(jié)點(diǎn)
transient Node first;

//尾節(jié)點(diǎn)
transient Node last;
4.節(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu)

在此之前,先介紹一下雙端鏈表的數(shù)據(jù)結(jié)構(gòu)

private static class Node {
        //節(jié)點(diǎn)的值
        E item;
        //下一個(gè)節(jié)點(diǎn),如果為尾節(jié)點(diǎn),則此值為null
        Node next;
        //前一個(gè)節(jié)點(diǎn),如果為首節(jié)點(diǎn),則此值為null
        Node prev;

        Node(Node prev, E element, Node next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
5.重要方法
//向鏈表頭添加元素
private void linkFirst(E e) {
        final Node f = first;
        //設(shè)置新節(jié)點(diǎn),令首節(jié)點(diǎn)等于新節(jié)點(diǎn),并將新節(jié)點(diǎn)的next指向原來的首節(jié)點(diǎn)
        final Node newNode = new Node<>(null, e, f);
        first = newNode;
        //如果原來首節(jié)點(diǎn)為空,代表為空鏈表,則令尾節(jié)點(diǎn)也為新節(jié)點(diǎn)
          ,否則,令原來首節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)為新節(jié)點(diǎn)
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        //元素個(gè)數(shù)與修改次數(shù)進(jìn)行增加
        size++;
        modCount++;
    }
    
//向鏈表尾添加元素
void linkLast(E e) {
        final Node l = last;
        //設(shè)置新節(jié)點(diǎn),令尾節(jié)點(diǎn)指向新節(jié)點(diǎn),并且將新節(jié)點(diǎn)的prev指向原來的尾節(jié)點(diǎn)
        final Node newNode = new Node<>(l, e, null);
        last = newNode;
        //如果原來尾節(jié)點(diǎn)為空,代表為空鏈表,則令首節(jié)點(diǎn)也為新節(jié)點(diǎn)
          ,否則,令原來尾節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)為新節(jié)點(diǎn)
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

//在給定節(jié)點(diǎn)之前插入對(duì)應(yīng)節(jié)點(diǎn)
void linkBefore(E e, Node succ) {
        //獲取給定節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn),設(shè)為pred
        final Node pred = succ.prev;
        //設(shè)置新節(jié)點(diǎn),令其prev為給定節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn),next為給定節(jié)點(diǎn)
        final Node newNode = new Node<>(pred, e, succ);
        //同時(shí)設(shè)置給定節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)為新節(jié)點(diǎn)
        succ.prev = newNode;
        //判斷pred是否為空,如果是,那么新節(jié)點(diǎn)就是首節(jié)點(diǎn)
          ,否則,直接令pred的下一個(gè)節(jié)點(diǎn)為新節(jié)點(diǎn)
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

//刪除首節(jié)點(diǎn)
private E unlinkFirst(Node f) {
        final E element = f.item;
        final Node next = f.next;
        //將首節(jié)點(diǎn)中相關(guān)引用置空,防止內(nèi)存泄漏
        f.item = null;
        f.next = null;
        //令首節(jié)點(diǎn)為首節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
        first = next;
        //如果首節(jié)點(diǎn)為空,那么直接將尾節(jié)點(diǎn)也置空,
          否則,將當(dāng)前首節(jié)點(diǎn)的prev置為null
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        modCount++;
        return element;
    }
//刪除尾節(jié)點(diǎn)
private E unlinkLast(Node l) {
        final E element = l.item;
        final Node prev = l.prev;
        //將尾節(jié)點(diǎn)中相關(guān)引用置空,防止內(nèi)存泄漏
        l.item = null;
        l.prev = null; 
        //令尾節(jié)點(diǎn)為尾節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)
        last = prev;
        //如果尾節(jié)點(diǎn)為空,那么直接將首節(jié)點(diǎn)也置空,
          否則,將當(dāng)前尾節(jié)點(diǎn)的next置為null
        if (prev == null)
            first = null;
        else
            prev.next = null;
        size--;
        modCount++;
        return element;
    }
    
//刪除指定元素
E unlink(Node x) {
        final E element = x.item;
        final Node next = x.next;
        final Node prev = x.prev;
        
        //如果指定節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)為空,代表制定節(jié)點(diǎn)為首節(jié)點(diǎn)
          ,令首節(jié)點(diǎn)為指定節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),否則,指定節(jié)點(diǎn)
          的prev的next節(jié)點(diǎn)為其自身的next節(jié)點(diǎn),并且令指定節(jié)點(diǎn)
          的prev節(jié)點(diǎn)為null
        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }
        
        //同理,如果指定節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)為null,代表指定節(jié)點(diǎn)為尾節(jié)點(diǎn),令
          尾節(jié)點(diǎn)等于指定節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn),否則,指定節(jié)點(diǎn)的next節(jié)點(diǎn)的prev節(jié)點(diǎn)
          等于其自身的prev節(jié)點(diǎn),且令自身的next節(jié)點(diǎn)等于null
        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }
        //最后,將指定節(jié)點(diǎn)的item也置為null,防止內(nèi)存泄漏
        x.item = null;
        size--;
        modCount++;
        return element;
    }
//按照索引值與對(duì)應(yīng)集合類進(jìn)行批量添加
public boolean addAll(int index, Collection c) {
        //檢驗(yàn)index是否合法,就是檢查其是否在[0,size]范圍內(nèi),如果index為size,就是尾節(jié)點(diǎn)
        checkPositionIndex(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        //如果集合類長(zhǎng)度為0,那么直接返回失敗
        if (numNew == 0)
            return false;
        
        //如果index與size大小相等,直接設(shè)置插入位置為尾節(jié)點(diǎn)
          ,否則,進(jìn)行遍歷查找節(jié)點(diǎn),設(shè)置查找到的節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)為插入節(jié)點(diǎn)
        Node pred, succ;
        if (index == size) {
            succ = null;
            pred = last;
        } else {
            succ = node(index);
            pred = succ.prev;
        }
        
        //循環(huán)插入
        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
            Node newNode = new Node<>(pred, e, null);
            //如果pred==null,代表index=0,此時(shí)直接插入首節(jié)點(diǎn),令
              首節(jié)點(diǎn)等于新節(jié)點(diǎn),否則,直接令pred的下一個(gè)節(jié)點(diǎn)為新節(jié)點(diǎn),然后依序插入
            if (pred == null)
                first = newNode;
            else
                pred.next = newNode;
            pred = newNode;
        }
        //如果,succ==null,代表index==size,則是直接從
          尾部進(jìn)行插入,所以,直接令尾節(jié)點(diǎn)指向插入的最后一個(gè)節(jié)點(diǎn)即可
          ,否則,令最后一個(gè)插入節(jié)點(diǎn)的next等于succ,
          令succ的prev等于最后一個(gè)插入節(jié)點(diǎn)即可(其實(shí)就是進(jìn)行了一個(gè)銜接)
        if (succ == null) {
            last = pred;
        } else {
            pred.next = succ;
            succ.prev = pred;
        }
        //對(duì)元素?cái)?shù)量進(jìn)行增加
        size += numNew;
        modCount++;
        return true;
    }
//根據(jù)索引查找對(duì)應(yīng)的節(jié)點(diǎn)(調(diào)用這個(gè)方法的方法已經(jīng)判斷過index,所以直接使用)
Node node(int index) {
        //如果index靠近左邊,從first開始遍歷,否則,從last開始遍歷
        if (index < (size >> 1)) {
            Node x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77318.html

相關(guān)文章

  • LinkedList源碼解析

    摘要:我們來看相關(guān)源碼我們看到封裝的和操作其實(shí)就是對(duì)頭結(jié)點(diǎn)的操作。迭代器通過指針,能指向下一個(gè)節(jié)點(diǎn),無需做額外的遍歷,速度非常快。不同的遍歷性能差距極大,推薦使用迭代器進(jìn)行遍歷。LinkedList類介紹 上一篇文章我們介紹了JDK中ArrayList的實(shí)現(xiàn),ArrayList底層結(jié)構(gòu)是一個(gè)Object[]數(shù)組,通過拷貝,復(fù)制等一系列封裝的操作,將數(shù)組封裝為一個(gè)幾乎是無限的容器。今天我們來介紹JD...

    roundstones 評(píng)論0 收藏0
  • Java集合之LinkedList源碼解析

    摘要:快速失敗在用迭代器遍歷一個(gè)集合對(duì)象時(shí),如果遍歷過程中對(duì)集合對(duì)象的內(nèi)容進(jìn)行了修改增加刪除修改,則會(huì)拋出。原理由于迭代時(shí)是對(duì)原集合的拷貝進(jìn)行遍歷,所以在遍歷過程中對(duì)原集合所作的修改并不能被迭代器檢測(cè)到,所以不會(huì)觸發(fā)。 原文地址 LinkedList 在Java.util包下 繼承自AbstractSequentialList 實(shí)現(xiàn) List 接口,能對(duì)它進(jìn)行隊(duì)列操作。 實(shí)現(xiàn) Deque ...

    DC_er 評(píng)論0 收藏0
  • LinkedList 基本示例及源碼解析

    摘要:對(duì)于不可修改的列表來說,程序員需要實(shí)現(xiàn)列表迭代器的和方法介紹這個(gè)接口也是繼承類層次的核心接口,以求最大限度的減少實(shí)現(xiàn)此接口的工作量,由順序訪問數(shù)據(jù)存儲(chǔ)例如鏈接鏈表支持。 一、JavaDoc 簡(jiǎn)介 LinkedList雙向鏈表,實(shí)現(xiàn)了List的 雙向隊(duì)列接口,實(shí)現(xiàn)了所有l(wèi)ist可選擇性操作,允許存儲(chǔ)任何元素(包括null值) 所有的操作都可以表現(xiàn)為雙向性的,遍歷的時(shí)候會(huì)從首部到尾部進(jìn)行...

    senntyou 評(píng)論0 收藏0
  • LinkedList源碼解析

    摘要:我們來看相關(guān)源碼我們看到封裝的和操作其實(shí)就是對(duì)頭結(jié)點(diǎn)的操作。迭代器通過指針,能指向下一個(gè)節(jié)點(diǎn),無需做額外的遍歷,速度非常快。不同的遍歷性能差距極大,推薦使用迭代器進(jìn)行遍歷。LinkedList類介紹 上一篇文章我們介紹了JDK中ArrayList的實(shí)現(xiàn),ArrayList底層結(jié)構(gòu)是一個(gè)Object[]數(shù)組,通過拷貝,復(fù)制等一系列封裝的操作,將數(shù)組封裝為一個(gè)幾乎是無限的容器。今天我們來介紹JD...

    番茄西紅柿 評(píng)論0 收藏0
  • LinkedList源碼解析

    摘要:我們來看相關(guān)源碼我們看到封裝的和操作其實(shí)就是對(duì)頭結(jié)點(diǎn)的操作。迭代器通過指針,能指向下一個(gè)節(jié)點(diǎn),無需做額外的遍歷,速度非???。不同的遍歷性能差距極大,推薦使用迭代器進(jìn)行遍歷。LinkedList類介紹 上一篇文章我們介紹了JDK中ArrayList的實(shí)現(xiàn),ArrayList底層結(jié)構(gòu)是一個(gè)Object[]數(shù)組,通過拷貝,復(fù)制等一系列封裝的操作,將數(shù)組封裝為一個(gè)幾乎是無限的容器。今天我們來介紹JD...

    番茄西紅柿 評(píng)論0 收藏0
  • LinkedList源碼解析(一)

    摘要:基本屬性存儲(chǔ)數(shù)據(jù)量指向第一個(gè)節(jié)點(diǎn)的指針指向最后一個(gè)節(jié)點(diǎn)的指針。 基本屬性 transient int size = 0;//存儲(chǔ)數(shù)據(jù)量 /** * Pointer to first node. */ transient Node first;//指向第一個(gè)節(jié)點(diǎn)的指針 /** * Pointer to last node...

    GT 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<