LinkedList源碼初探

準(zhǔn)備:

LinkedList是基于鏈表(雙向循環(huán)鏈表)結(jié)構(gòu)的一種List耻矮,在分析LinkedList源碼之前我們先看看鏈表

1、鏈表概念

鏈表是由一系列非連續(xù)的節(jié)點(diǎn)組成的存儲(chǔ)結(jié)構(gòu)纫普,簡(jiǎn)單分下類的話默刚,鏈表又分為單向鏈表和雙向鏈表媚创,而單向/雙向鏈表又可以分為循環(huán)鏈表和非循環(huán)鏈表丹允,下面簡(jiǎn)單就這四種鏈表進(jìn)行圖解說(shuō)明。

1.1携茂、單向鏈表

單向鏈表就是通過(guò)每個(gè)結(jié)點(diǎn)的指針指向下一個(gè)結(jié)點(diǎn)從而鏈接起來(lái)的結(jié)構(gòu)你踩,最后一個(gè)節(jié)點(diǎn)的next指向null。

單向鏈表.jpg
1.2讳苦、單向循環(huán)鏈表

單向循環(huán)鏈表和單向列表的不同是带膜,最后一個(gè)節(jié)點(diǎn)的next不是指向null,而是指向head節(jié)點(diǎn)鸳谜,形成一個(gè)“環(huán)”膝藕。

單向循環(huán)鏈表.jpg
1.3、雙向鏈表

從名字就可以看出咐扭,雙向鏈表是包含兩個(gè)指針的芭挽,pre指向前一個(gè)節(jié)點(diǎn),next指向后一個(gè)節(jié)點(diǎn)蝗肪,但是第一個(gè)節(jié)點(diǎn)head的pre指向null袜爪,最后一個(gè)節(jié)點(diǎn)的tail指向null。

雙向鏈表.jpg
1.4薛闪、雙向循環(huán)鏈表

雙向循環(huán)鏈表和雙向鏈表的不同在于辛馆,第一個(gè)節(jié)點(diǎn)的pre指向最后一個(gè)節(jié)點(diǎn),最后一個(gè)節(jié)點(diǎn)的next指向第一個(gè)節(jié)點(diǎn)豁延,也形成一個(gè)“環(huán)”怀各。而LinkedList就是基于雙向循環(huán)鏈表設(shè)計(jì)的。

雙向循環(huán)鏈表.jpg

更形象的解釋下就是:雙向循環(huán)鏈表就像一群小孩手牽手圍成一個(gè)圈术浪,第一個(gè)小孩的右手拉著第二個(gè)小孩的左手,第二個(gè)小孩的左手拉著第一個(gè)小孩的右手寿酌。胰苏。。最后一個(gè)小孩的右手拉著第一個(gè)小孩的左手醇疼。

附圖:

timg.jpg

一 :結(jié)構(gòu)關(guān)系

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, Serializable{
結(jié)構(gòu).png
結(jié)構(gòu)圖.png

可以看出LinkedList 繼承AbstractSequentialList 抽象類硕并,實(shí)現(xiàn)List法焰,Deque,Cloneable倔毙,Serializable 幾個(gè)接口埃仪,AbstractSequentialList 繼承 AbstractList,是對(duì)其中方法的再抽象陕赃,其主要作用是最大限度地減少了實(shí)現(xiàn)受“連續(xù)訪問”數(shù)據(jù)存儲(chǔ)(如鏈接列表)支持的此接口所需的工作卵蛉,簡(jiǎn)單說(shuō)就是,如果需要快速的添加刪除數(shù)據(jù)等么库,用AbstractSequentialList抽象類傻丝,若是需要快速隨機(jī)的訪問數(shù)據(jù)等用AbstractList抽象類(詳細(xì)說(shuō)明會(huì)在iterator 分析中進(jìn)行解釋)。

注意:

Deque 是一個(gè)雙向隊(duì)列诉儒,也就是既可以先入先出葡缰,又可以先入后出,再直白一點(diǎn)就是既可以在頭部添加元素又在尾部添加元素忱反,既可以在頭部獲取元素又可以在尾部獲取元素泛释。看下Deque的定義:

public interface Deque<E> extends Queue<E> {
    void addFirst(E e);
    boolean offerFirst(E e);
    boolean offerLast(E e);
    E removeFirst();
    E removeLast();
    E pollFirst();
    E pollLast();
    E getFirst();
    E getLast();
    E peekFirst();
    E peekLast();
    boolean removeFirstOccurrence(Object o);
    boolean removeLastOccurrence(Object o);
    // *** Queue methods ***
    boolean add(E e);
    boolean offer(E e);
    E remove();
    E poll();
    E element();
    E peek();
    // *** Stack methods ***
    void push(E e);
    E pop();
   // *** Collection methods ***
    boolean remove(Object o);
    boolean contains(Object o);
    public int size();
    Iterator<E> iterator();
    Iterator<E> descendingIterator();
}

二 :介紹

(1):LinkedList是基于雙向循環(huán)鏈表實(shí)現(xiàn)的温算,除了可以當(dāng)做鏈表來(lái)操作外怜校,它還可以當(dāng)做棧、隊(duì)列和雙端隊(duì)列來(lái)使用米者。
(2):是一種鏈表類型的數(shù)據(jù)結(jié)構(gòu)韭畸,支持高效的插入和刪除操作,同時(shí)也實(shí)現(xiàn)了Deque接口蔓搞,使得LinkedList類也具有隊(duì)列的特性胰丁。LinkedList類的底層實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)是一個(gè)雙端的鏈表。
(3): 不是線程安全的
(4):LinkedList實(shí)現(xiàn)了Serializable接口喂分,因此它支持序列化锦庸,能夠通過(guò)序列化傳輸,實(shí)現(xiàn)了Cloneable接口蒲祈,能被克隆甘萧。

三 :重要知識(shí)點(diǎn)

(1):重要屬性
(2):LinkedList的創(chuàng)建:即構(gòu)造器
(3):重點(diǎn)內(nèi)部類以及重點(diǎn)方法
(4):線程安全與否以及解決方案

四 :源碼淺析

4.1重要屬性:
    //集合長(zhǎng)度
    transient int size = 0;

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

    //尾節(jié)點(diǎn)
    transient Node<E> last;



這里注意LinkedList的元素結(jié)構(gòu),是一個(gè)node元素梆掸,是一個(gè)雙向鏈表扬卷,我們看看node的構(gòu)成

    // 雙向鏈表的節(jié)點(diǎn)所對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)。  
    // 包含3部分:上一節(jié)點(diǎn)酸钦,下一節(jié)點(diǎn)怪得,當(dāng)前節(jié)點(diǎn)值。  
    private static class Node<E> {
        E item;// 當(dāng)前節(jié)點(diǎn)所包含的值  
        Node<E> next;// 下一個(gè)節(jié)點(diǎn)
        Node<E> prev; // 上一個(gè)節(jié)點(diǎn)  

        /**  
         * 鏈表節(jié)點(diǎn)的構(gòu)造函數(shù)。  
         * 參數(shù)說(shuō)明:  
         *   element  —— 節(jié)點(diǎn)所包含的數(shù)據(jù)  
         *   next     —— 下一個(gè)節(jié)點(diǎn)  
         *   previous —— 上一個(gè)節(jié)點(diǎn)  
         */
        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

注意上邊的node源碼徒恋,LinkedList類中有一個(gè)內(nèi)部私有類Node蚕断,這個(gè)類就代表雙端鏈表的節(jié)點(diǎn)Node。這個(gè)類有三個(gè)屬性入挣,分別是前驅(qū)節(jié)點(diǎn)亿乳,本節(jié)點(diǎn)的值,后繼結(jié)點(diǎn)径筏。

注意這個(gè)節(jié)點(diǎn)的初始化方法葛假,給定三個(gè)參數(shù),分別前驅(qū)節(jié)點(diǎn)匠璧,本節(jié)點(diǎn)的值桐款,后繼結(jié)點(diǎn)。這個(gè)方法將在LinkedList的實(shí)現(xiàn)中多次調(diào)用夷恍。

4.2創(chuàng)建一個(gè)LinkedList:
API提供了兩種創(chuàng)建LinkedList的構(gòu)造方法
(1): public LinkedList()  //無(wú)參構(gòu)造創(chuàng)建

(2):public LinkedList(Collection<? extends E> c)//帶參構(gòu)造創(chuàng)建
4.3向LinkedList中添加元素:
LinkedList的添加方法有好幾個(gè)
(1):public boolean add(E e) 
(1):public boolean addAll(Collection<? extends E> c) 
(1):public void add(int index, E element)
(1):public void addFirst(E e)
(1):public void addLast(E e)

這里我們主要分析add(E e),以下是源碼:

    //追加節(jié)點(diǎn)(尾部添加)
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

    //在鏈表尾部添加一個(gè)元素
    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++;
    }
t添加圖解.jpg

增加元素的實(shí)現(xiàn)其實(shí)很簡(jiǎn)單魔眨,只要理解了雙向鏈表的存儲(chǔ)結(jié)構(gòu),掌握增加的核心邏輯就可以了酿雪。這里總結(jié)一下核心邏輯:1.將元素轉(zhuǎn)換為鏈表節(jié)點(diǎn)遏暴,2.增加該節(jié)點(diǎn)的前后引用(即pre和next分別指向哪一個(gè)節(jié)點(diǎn)),3.前后節(jié)點(diǎn)對(duì)該節(jié)點(diǎn)的引用(前節(jié)點(diǎn)的next指向該節(jié)點(diǎn)指黎,后節(jié)點(diǎn)的pre指向該節(jié)點(diǎn))朋凉。其實(shí)就是前后變換的互相指向關(guān)系

4.4從LinkedList中移除元素:
同樣LinkedList的刪除方法也有好幾個(gè)
(1):public boolean remove(Object o)
(2):public E remove() 
(3):public E remove(int index)
(4):public E removeFirst()
(5):public E removeLast()

這里一樣,我們重點(diǎn)看public E remove() 

    //刪除并返回第一個(gè)節(jié)點(diǎn)  若LinkedList的大小為0,則拋出異常
    public E remove() {
        return removeFirst();
    }

    //移除首節(jié)點(diǎn)并返回該節(jié)點(diǎn)
    public E removeFirst() {
        final Node<E> f = first;
        if (f == null) throw new NoSuchElementException();
        return unlinkFirst(f);
    }

    //私有方法:解開首節(jié)點(diǎn)連接并移除該節(jié)點(diǎn)
    private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;//獲取首節(jié)點(diǎn)
        final Node<E> next = f.next;//獲取其下一個(gè)節(jié)點(diǎn)
        f.item = null;
        f.next = null; // help GC
        first = next;
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;//容量--
        modCount++;
        return element;
    }

上面對(duì)于鏈表增加元素總結(jié)了醋安,一句話就是“改變前后的互相指向關(guān)系”杂彭,刪除也是同樣的道理,由于節(jié)點(diǎn)被刪除吓揪,該節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)和下一個(gè)節(jié)點(diǎn)互相拉一下小手就可以了亲怠,注意的是“互相”,不能一廂情愿柠辞。

4.5修改LinkedList中某個(gè)元素:
    //設(shè)置index位置對(duì)應(yīng)的節(jié)點(diǎn)的值為element 
    public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
    }

set方法看起來(lái)簡(jiǎn)單了很多团秽,只要修改該節(jié)點(diǎn)上的元素就好了,但是不要忽略了這里的 node(index)方法叭首,重點(diǎn)就是它习勤。

4.5查詢LinkedList中某個(gè)元素:
LinkedList提供了各種方式的get方法方便開發(fā)調(diào)用
(1):public E get(int index)
(2):public E getFirst() 
(3):public E getLast()

主動(dòng)看public E get(int index)索引獲取源碼:
    // 返回LinkedList指定位置的元素 
    public E get(int index) {
        checkElementIndex(index);//檢查索引
        return node(index).item;//注意,這里item才是真正的數(shù)據(jù)焙格,Node并不是
    }

    //返回指定元素索引中的(非空)節(jié)點(diǎn)
    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;
        }
    }

現(xiàn)在知道了图毕,LinkedList是通過(guò)從header開始index計(jì)為0,然后一直往下遍歷(next)眷唉,直到到底index位置吴旋。為了優(yōu)化查詢效率损肛,LinkedList采用了二分查找(這里說(shuō)的二分只是簡(jiǎn)單的一次二分),判斷index與size中間位置的距離荣瑟,采取從header向后還是向前查找。
到這里我們明白摩泪,基于雙向循環(huán)鏈表實(shí)現(xiàn)的LinkedList笆焰,通過(guò)索引Index的操作時(shí)低效的,index所對(duì)應(yīng)的元素越靠近中間所費(fèi)時(shí)間越長(zhǎng)见坑。而向鏈表兩端插入和刪除元素則是非常高效的(如果不是兩端的話嚷掠,都需要對(duì)鏈表進(jìn)行遍歷查找)。

4.6容量:

    public int size() {
        return size ;
    }
 
    public boolean isEmpty() {
        return size() == 0;
    }
4.6LinkedList實(shí)現(xiàn)的Deque雙端隊(duì)列 :
    //將元素E添加到鏈表末尾
    public boolean offer(E e) {
        return add(e);
    }

    //刪除并返回第一個(gè)節(jié)點(diǎn)  若LinkedList的大小為0,則返回null
    public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

    //刪除并返回第一個(gè)節(jié)點(diǎn)  
    public E pop() {
        return removeFirst();
    }

    //返回第一個(gè)節(jié)點(diǎn)  若LinkedList的大小為0,則返回null
    public E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
    }

    //獲取首節(jié)點(diǎn)
    public E getFirst() {
        final Node<E> f = first;
        if (f == null) throw new NoSuchElementException();
        return f.item;
    }
 
    //將e插入到雙向鏈表開頭  
    public void push(E e) {
        addFirst(e);
    }

   //添加頭節(jié)點(diǎn)
    public void addFirst(E e) {
        linkFirst(e);
    }
4.6迭代元素:

如果仔細(xì)觀察荞驴,你會(huì)發(fā)現(xiàn)在 LinkedList中是沒有自己實(shí)現(xiàn) iterator的不皆,如果這樣調(diào)用:

LinkedList<Integer> list = new LinkedList<>();
Iterator<Integer> it = list.iterator();

你會(huì)發(fā)現(xiàn)它調(diào)用的是 AbstractSequentialList中的 iterator(),返回的還是 AbstractList 中的 listIterator()熊楼,而在 LinkedList中實(shí)現(xiàn)了自己的 listIterator霹娄,因此如果進(jìn)行迭代,還是老老實(shí)實(shí)用 LinkedList中的 listIterator比較好鲫骗。LinkedList中還提供了逆序的 Iterator—— DescendingIterator犬耻,實(shí)際上它也只是簡(jiǎn)單的對(duì) ListIterator進(jìn)行了封裝:

    public Iterator<E> iterator() {
        return listIterator();
    }

    public ListIterator<E> listIterator() {
        return listIterator(0);
    }

    public ListIterator<E> listIterator(final int index) {
        rangeCheckForAdd(index);

        return new ListItr(index);//最終返回的是一個(gè)Listltr的迭代器
    }

看看Listltr源碼(是AbstractSequentialList的私有內(nèi)部類)

    private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            cursor = index;
        }

        public boolean hasPrevious() {
            return cursor != 0;
        }

        public E previous() {
            checkForComodification();
            try {
                int i = cursor - 1;
                E previous = get(i);
                lastRet = cursor = i;
                return previous;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

        public int nextIndex() {
            return cursor;
        }

        public int previousIndex() {
            return cursor-1;
        }

        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.set(lastRet, e);
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                AbstractList.this.add(i, e);
                lastRet = -1;
                cursor = i + 1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

五 :線程安全問題

LinkedList和arrayList一樣都是線程不安全的,如果在多線程程序中有多個(gè)線程訪問LinkedList的話會(huì)出現(xiàn)拋出ConcurrentModificationException

   final void checkForComodification() {
        if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    }

代碼中执泰,modCount記錄了LinkedList結(jié)構(gòu)被修改的次數(shù)枕磁。Iterator初始化時(shí),expectedModCount=modCount术吝。任何通過(guò)Iterator修改LinkedList結(jié)構(gòu)的行為都會(huì)同時(shí)更新expectedModCount和modCount计济,使這兩個(gè)值相等。通過(guò)LinkedList對(duì)象修改其結(jié)構(gòu)的方法只更新modCount排苍。所以假設(shè)有兩個(gè)線程A和B沦寂。A通過(guò)Iterator遍歷并修改LinkedList,而B纪岁,與此同時(shí)凑队,通過(guò)對(duì)象修改其結(jié)構(gòu),那么Iterator的相關(guān)方法就會(huì)拋出異常幔翰。這是相對(duì)容易發(fā)現(xiàn)的由線程競(jìng)爭(zhēng)造成的錯(cuò)誤漩氨。

測(cè)試代碼:

/**
 * ClassName: TestLinkedList
 * @author lvfang
 * @Desc: TODO
 * @date 2017-9-21
 */
public class TestLinkedList implements Runnable {
    
    private LinkedList<Integer> list = null;    
    public TestLinkedList(LinkedList<Integer> list){
        this.list = list;
    }
    
    @Override
    public void run() {
        for(int i=0;i<10;i++) list.add(i);
        System.out.println(list.size());
    }
    
    /**
     * LinkedList線程安全測(cè)試
     * @param args
     */
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        //啟動(dòng)5個(gè)線程,每個(gè)線程向集合中添加10條數(shù)據(jù)遗增,最終應(yīng)該是50
        for (int i = 0; i < 5; i++) {
            new Thread(new TestLinkedList(list)).start();
        }
    }   
}
解決方案

方案一:Collections類的同步list方法
List<String> linkedList = Collections.synchronizedList(new LinkedList<String>())

方案二:ConcurrentLinkedQueue代替linkedList

六 :總結(jié)(LinkedList和ArrayList的大致區(qū)別)

1叫惊、ArrayList繼承于 AbstractList, LinkedList繼承于 AbstractSequentialList做修;
2霍狰、ArrayList基于數(shù)組抡草, LinkedList基于雙向鏈表,對(duì)于隨機(jī)訪問蔗坯, ArrayList比較占優(yōu)勢(shì)康震,LinkedList插入、刪除元素比較快宾濒,如果只要調(diào)整指針的指向那么時(shí)間復(fù)雜度是O(1),但是如果針對(duì)特定位置需要遍歷時(shí)腿短,時(shí)間復(fù)雜度是O(n),也就是LinkedList在隨機(jī)訪問元素的話比較慢绘梦;
3橘忱、LinkedList沒有實(shí)現(xiàn)自己的 Iterator,但是有 ListIterator和 DescendingIterator卸奉;
4钝诚、LinkedList需要更多的內(nèi)存,因?yàn)?ArrayList的每個(gè)索引的位置是實(shí)際的數(shù)據(jù)榄棵,而 LinkedList中的每個(gè)節(jié)點(diǎn)中存儲(chǔ)的是實(shí)際的數(shù)據(jù)和前后節(jié)點(diǎn)的位置凝颇;
5、ArrayList 和 LinkedList都是非同步的集合秉继。
6祈噪、和ArrayList一樣,LinkedList也是非線程安全的尚辑,只有在單線程下才可以使用辑鲤。為了防止非同步訪問,可以采用如下方式創(chuàng)建LinkedList:List list= Collections.synchronizedList(new LinkedList());
7杠茬、LinkedList基于雙向鏈表實(shí)現(xiàn)月褥,元素都可以為null。

七:推薦相關(guān)文章

http://www.cnblogs.com/tstd/p/5046819.html瓢喉、
https://segmentfault.com/a/1190000003509201

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宁赤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子栓票,更是在濱河造成了極大的恐慌决左,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件走贪,死亡現(xiàn)場(chǎng)離奇詭異佛猛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)坠狡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門继找,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人逃沿,你說(shuō)我怎么就攤上這事婴渡』盟” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵边臼,是天一觀的道長(zhǎng)哄尔。 經(jīng)常有香客問我,道長(zhǎng)硼瓣,這世上最難降的妖魔是什么究飞? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮堂鲤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘媒峡。我一直安慰自己瘟栖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布谅阿。 她就那樣靜靜地躺著半哟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪签餐。 梳的紋絲不亂的頭發(fā)上寓涨,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音氯檐,去河邊找鬼戒良。 笑死,一個(gè)胖子當(dāng)著我的面吹牛冠摄,可吹牛的內(nèi)容都是我干的糯崎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼河泳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼沃呢!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起拆挥,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤薄霜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后纸兔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惰瓜,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年食拜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鸵熟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡负甸,死狀恐怖流强,靈堂內(nèi)的尸體忽然破棺而出痹届,到底是詐尸還是另有隱情,我是刑警寧澤打月,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布队腐,位于F島的核電站,受9級(jí)特大地震影響奏篙,放射性物質(zhì)發(fā)生泄漏柴淘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一秘通、第九天 我趴在偏房一處隱蔽的房頂上張望为严。 院中可真熱鬧,春花似錦肺稀、人聲如沸第股。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夕吻。三九已至,卻和暖如春繁仁,著一層夾襖步出監(jiān)牢的瞬間涉馅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工黄虱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留稚矿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓悬钳,卻偏偏與公主長(zhǎng)得像盐捷,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子默勾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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

  • 一.線性表 定義:零個(gè)或者多個(gè)元素的有限序列碉渡。也就是說(shuō)它得滿足以下幾個(gè)條件:??①該序列的數(shù)據(jù)元素是有限的。??②...
    Geeks_Liu閱讀 2,693評(píng)論 1 12
  • 前言 今天來(lái)介紹下LinkedList母剥,在集合框架整體框架一章中滞诺,我們介紹了List接口,LinkedList與A...
    嘟爺MD閱讀 3,579評(píng)論 11 37
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等环疼,對(duì)于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,488評(píng)論 0 3
  • Collection接口 Collection接口是所有集合的祖先類习霹。他有兩個(gè)構(gòu)造方法,一個(gè)無(wú)參構(gòu)造炫隶,一個(gè)是帶Co...
    夜幕繁華閱讀 583評(píng)論 0 0
  • 大數(shù)據(jù)時(shí)代:整合營(yíng)銷應(yīng)該如何做? 諸葛io認(rèn)為淋叶,大數(shù)據(jù)時(shí)代的全面來(lái)臨,不僅僅是讓企業(yè)廣告投放更加精準(zhǔn)伪阶,我們的生活煞檩、...
    小大白閱讀 508評(píng)論 0 2