List接口下的集合源碼分析——LinkedList

源碼版本JDK1.8

今天帶來(lái)的是List的另一種實(shí)現(xiàn)——LinkedList滔以,這是一種基于雙向鏈表實(shí)現(xiàn)的列表鲁驶。接下來(lái)讓我們通過(guò)源碼來(lái)分析一下它吧椅文。

關(guān)于源碼中的一些小改動(dòng)

在JDK1.6及之前冒晰,LinkedList底層是一個(gè)雙向循環(huán)鏈表,容器中的元素都是靜態(tài)內(nèi)部類Entry的對(duì)象蚜枢,列表中必有一個(gè)空頭結(jié)點(diǎn)缸逃;
在JDK1.7及之后,LinkedList底層是一個(gè)雙向非循環(huán)鏈表厂抽,容器中的元素都是靜態(tài)內(nèi)部類Node的對(duì)象需频。
基于這些小差別,筆者分享下自己的見(jiàn)解:

  • 使用非循環(huán)鏈表后筷凤,可以少一個(gè)空的頭結(jié)點(diǎn)昭殉,在頭尾加入元素時(shí)可以少一些引用操作(對(duì)于循環(huán)鏈表來(lái)說(shuō),由于首尾相連,還是需要處理兩頭的前驅(qū)和后繼引用饲化。而非循環(huán)鏈表只需要處理一邊f(xié)irst.previous/last.next莽鸭,所以理論上非循環(huán)鏈表更高效吗伤。恰恰在兩頭(鏈頭/鏈尾) 操作是最普遍的)
  • 對(duì)于Entry改變成Node吃靠,本質(zhì)上是沒(méi)有差別的∽阆可能大家對(duì)Entry的印象是Map中實(shí)現(xiàn)的一個(gè)內(nèi)部類巢块,用來(lái)存儲(chǔ)鍵值對(duì)<key,value>,而在LinkedList中是要存儲(chǔ)<previous,item,next>巧号,不便于凸顯Entry存儲(chǔ)鍵值對(duì)的特性吧族奢,容易造成混淆。(這只是個(gè)人的猜測(cè)丹鸿,若有不同見(jiàn)解可以交流)
    補(bǔ)充:不論是Entry還是Node越走,都是外部類LinkedList實(shí)現(xiàn)的一個(gè)靜態(tài)內(nèi)部類,這么做是把一個(gè)類相關(guān)的類型放到內(nèi)部靠欢,提高類的高內(nèi)聚廊敌,而且通常情況下只有該外部類會(huì)調(diào)用其內(nèi)部類,如果把Entry或者Node放到外部门怪,明顯就提高了耦合性骡澈,對(duì)于其他集合類型的內(nèi)部實(shí)現(xiàn)來(lái)說(shuō)都是不利的。
    再有一個(gè)掷空,內(nèi)部類會(huì)隨著外部類的加載而產(chǎn)生肋殴。
    傳送門(mén):關(guān)于靜態(tài)內(nèi)部類
    雙向循環(huán)鏈表結(jié)構(gòu)

    雙向非循環(huán)鏈表結(jié)構(gòu)

一、LinkedList概述

在源碼中對(duì)LinkedList是這么描述的:

  • 雙向鏈表實(shí)現(xiàn) ListDeque接口坦弟。實(shí)現(xiàn)所有可選的列表操作护锤,并允許所有元素null。
  • 所有操作的執(zhí)行方式與雙向鏈表都是一樣的酿傍。索引到列表中的操作將從開(kāi)始或結(jié)束遍歷列表烙懦,無(wú)論哪個(gè)更接近指定的索引。
  • 此實(shí)現(xiàn)未同步拧粪。
    *此類的 iterator和listIterator方法返回的迭代器:如果在創(chuàng)建迭代器之后的任何時(shí)間對(duì)結(jié)構(gòu)進(jìn)行修改修陡,除了通過(guò)迭代器自己的remove}或{@code add方法,迭代器將拋出一個(gè)ConcurrentModificationException可霎。因此魄鸦,面對(duì)并發(fā)修改,迭代器快速而干凈地失敗癣朗,而不是在將來(lái)的未確定時(shí)間冒任意的拾因,非確定性行為的風(fēng)險(xiǎn)。

二、LinkedList的繼承绢记、實(shí)現(xiàn)關(guān)系

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  • 繼承自AbstractSequentialList扁达,而AbstractSequentialList父類為AbstractListAbstractSequentialList 實(shí)現(xiàn)了get(int index)蠢熄、set(int index, E element)跪解、add(int index, E element) 和 remove(int index)這些骨干性函數(shù)。
  • 實(shí)現(xiàn)List接口签孔,能對(duì)它進(jìn)行隊(duì)列操作叉讥。
  • 實(shí)現(xiàn)Deque接口,而DequeQueue的子接口饥追。Queue是一種隊(duì)列形式图仓,而Deque則是雙向隊(duì)列,它支持從兩個(gè)端點(diǎn)方向檢索和插入元素但绕,因此Deque既可以支持LIFO形式也可以支持LIFO形式救崔。Deque接口是一種比StackVector更為豐富的抽象數(shù)據(jù)形式,因?yàn)樗瑫r(shí)實(shí)現(xiàn)了以上兩者。傳送門(mén):Deque雙端隊(duì)列
  • 實(shí)現(xiàn)了Cloneable接口捏顺,即覆蓋了函數(shù)clone()六孵,能克隆。
  • 實(shí)現(xiàn)java.io.Serializable接口草丧,這意味著LinkedList支持序列化狸臣,能通過(guò)序列化去傳輸
    繼承實(shí)現(xiàn)關(guān)系.jpg

三、LinkedList屬性聲明及構(gòu)造函數(shù)

transient int size = 0;
transient Node<E> first;//指向第一個(gè)節(jié)點(diǎn)的指針
transient Node<E> last;//指向最后一個(gè)節(jié)點(diǎn)的指針
//構(gòu)造一個(gè)空列表
public LinkedList() {
    }
//按照集合的迭代器返回的順序構(gòu)造包含指定集合的??元素的列表
public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

—addAll()方法

public boolean addAll(Collection<? extends E> c) {
        return addAll(size, 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 {
            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;
    }

帶Collection值的構(gòu)造方法的執(zhí)行邏輯:
1)使用this()調(diào)用默認(rèn)的無(wú)參構(gòu)造函數(shù)昌执;
2)調(diào)用addAll()方法烛亦,傳入當(dāng)前的節(jié)點(diǎn)個(gè)數(shù)size,此時(shí)size為0懂拾,并將collection對(duì)象傳遞進(jìn)去煤禽;
3)檢查index有沒(méi)有數(shù)組越界的嫌疑;
4)將collection轉(zhuǎn)換成數(shù)組對(duì)象a岖赋;
5)循環(huán)遍歷a數(shù)組檬果,然后將a數(shù)組里面的元素創(chuàng)建成擁有前后連接的節(jié)點(diǎn),然后一個(gè)個(gè)按照順序連起來(lái)唐断;
6)修改當(dāng)前的節(jié)點(diǎn)個(gè)數(shù)size的值选脊;
7)操作次數(shù)modCount自增1。

四脸甘、LinkedList的方法

(一)添加元素

—在頭部添加元素

//在此列表的開(kāi)頭插入指定的元素
public void addFirst(E e) {
        linkFirst(e);
    }

private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        size++;
        modCount++;
    }

linkFirst(E e)是一個(gè)私有方法恳啥,所以無(wú)法在外部程序中調(diào)用(當(dāng)然,這是一般情況丹诀,你可以通過(guò)反射上面的還是能調(diào)用到的)钝的。
linkFirst(E e)首先構(gòu)造一個(gè)變量結(jié)點(diǎn)f = first翁垂,再 new一個(gè)newNode(為要添加進(jìn)來(lái)的節(jié)點(diǎn)),其前驅(qū)引用previous為null硝桩,后繼引用為f沿猜,再另頭結(jié)點(diǎn)指向新的節(jié)點(diǎn)newNode。
判斷碗脊,如果f == null啼肩,即列表為空,則頭尾節(jié)點(diǎn)指向同一個(gè)節(jié)點(diǎn)newNode望薄;如果不為空疟游,原來(lái)頭結(jié)點(diǎn)的前驅(qū)引用指向新節(jié)點(diǎn)newNode。
—在尾部添加元素

//將指定的元素追加到此列表的末尾
public void addLast(E e) {
        linkLast(e);
    }
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++;
    }

原理與在頭部添加元素類似痕支,可參照上面進(jìn)行解讀。
—在任意位置添加元素

// 在此列表中指定的位置插入指定的元素蛮原。將當(dāng)前在該位置的元素(如果有)和任何后續(xù)元素向右移(將一個(gè)添加到它們的索引)
public void add(int index, E element) {
        checkPositionIndex(index);
        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
//在非空節(jié)點(diǎn)succ之前插入元素e
void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

從源碼中看出卧须,若索引index==size,便直接在尾部添加元素儒陨;若不是花嘶,則調(diào)用linkBefore(E e, Node<E> succ)函數(shù)。
linkBefore(E e, Node<E> succ)首先構(gòu)造一個(gè)變量結(jié)點(diǎn)pred = succ.prev蹦漠,再 new一個(gè)newNode(為要添加進(jìn)來(lái)的節(jié)點(diǎn))椭员,其前驅(qū)引用previous為pred ,后繼引用為succ笛园,再另結(jié)點(diǎn)succ的前驅(qū)指向新的節(jié)點(diǎn)newNode隘击。
判斷,如果pred == null研铆,即列表為空埋同,則頭尾節(jié)點(diǎn)指向同一個(gè)節(jié)點(diǎn)newNode;如果不為空棵红,原來(lái)pred結(jié)點(diǎn)的后繼引用指向新節(jié)點(diǎn)newNode凶赁。

(二)查看元素

查看元素使用get方法。getFirst()逆甜、getLast()分別返回頭結(jié)點(diǎn)和尾節(jié)點(diǎn)虱肄。下面主要看看返回指定索引的方法get(int index)。

//返回此列表中指定位置的元素
public E get(int index) {
        checkElementIndex(index);
        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;
    }
//返回指定元素索引處的(非空)節(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;
        }
    }

get(int index)首先判斷給定索引是否存在交煞,若存在執(zhí)行node(index).item;其中item為元素的內(nèi)容咏窿。
node(int index)方法返回的是一個(gè)節(jié)點(diǎn)Node<E>,代碼中使用了類似二分法的查找方法來(lái)遍歷元素错敢。若index < (size >> 1)翰灾,即索引在前半部分缕粹,則從前向后依次查找;否則索引就在后半部分纸淮,從后向前依次查找平斩。
此段代碼能夠有效的提高遍歷效率,也反映了雙向鏈表的優(yōu)點(diǎn)——雙向鏈表增加了一點(diǎn)點(diǎn)的空間消耗(每個(gè)Node里面還要維護(hù)它的前置Node的引用)咽块,同時(shí)也增加了一定的編程復(fù)雜度绘面,卻大大提升了遍歷效率(體現(xiàn)在可以雙向遍歷)。

(三)刪除元素

removeFirst()侈沪,removeLast()分別用來(lái)刪除頭結(jié)點(diǎn)和尾結(jié)點(diǎn)揭璃,public E remove()方法刪除的也是列表的第一個(gè)元素,但是列表為空時(shí)使用不會(huì)拋出異常(removeFirst()會(huì)拋出異常)亭罪。
ArrayList一樣瘦馍,LinkedList支持按元素刪除和按下標(biāo)刪除,下面我們主要介紹public E remove(int index),public boolean remove(Object o)

//刪除此列表中指定位置的元素应役。將任何后續(xù)元素向左移(從它們的索引中減去一個(gè))情组。返回從列表中刪除的元素
public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }
//取消鏈接非空節(jié)點(diǎn)x
E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;
        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;
    }

按索引刪除remove(int index):
首先通過(guò)遍歷node(index)得到指定索引的節(jié)點(diǎn),后通過(guò)unlink()方法進(jìn)行刪除箩祥。
(1)x.prev = null;//前驅(qū)設(shè)置為null
(2)x.next = null;//后繼設(shè)置為null
(3)x.item = null;//內(nèi)容設(shè)置為null
至此節(jié)點(diǎn)x為空節(jié)點(diǎn)院崇,最后交給虛擬機(jī)gc完成回收,刪除操作結(jié)束袍祖。

//從列表中刪除指定元素的第一次出現(xiàn)(如果存在)底瓣。如果此列表不包含元素,則不會(huì)更改。
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;
    }

按元素刪除內(nèi)容remove(Object o):
不論元素內(nèi)容為空還是不為空蕉陋,均通過(guò)節(jié)點(diǎn)的遍歷捐凭,依次查找,若找到與指定內(nèi)容一致的節(jié)點(diǎn)則刪除并返回寺滚。
注意:該方法從列表中刪除第一次出現(xiàn)的指定元素柑营。


LinkedList的方法比較簡(jiǎn)單,沒(méi)有擴(kuò)容環(huán)節(jié)村视,翻閱源碼基本能懂官套,不存在什么大問(wèn)題。由于LinkedList實(shí)現(xiàn)了Deque接口蚁孔,該接口比List提供了更多的方法奶赔,包括 offer(),peek()杠氢,poll()等站刑。

//檢索,但不刪除此列表的頭(第一個(gè)元素)
public E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
    }
//檢索并刪除此列表的頭(第一個(gè)元素)
public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }
//檢索但不刪除此列表的第一個(gè)元素,如果此列表為空,則返回null
public E peekFirst() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
     }
//檢索但不刪除此列表的最后一個(gè)元素,如果此列表為空,則返回null
public E peekLast() {
        final Node<E> l = last;
        return (l == null) ? null : l.item;
    }
//檢索并刪除此列表的第一個(gè)元素,如果此列表為空,則返回null
public E pollFirst() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }
//檢索并刪除此列表的最后一個(gè)元素,如果此列表為空,則返回null
public E pollLast() {
        final Node<E> l = last;
        return (l == null) ? null : unlinkLast(l);
    }
//將指定的元素添加為此列表的尾部(最后一個(gè)元素)
public boolean offer(E e) {
        return add(e);
    }
//在此列表的前面插入指定的元素
public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }
//在此列表的結(jié)尾插入指定的元素
public boolean offerLast(E e) {
        addLast(e);
        return true;
    }
//將元素推送到此列表所表示的堆棧。換句話說(shuō),將元素插入此列表的前面,此方法等效于addFirst
public void push(E e) {
        addFirst(e);
    }
//此列表所表示的堆棧中彈出一個(gè)元素鼻百。換句話說(shuō),刪除并返回此列表的第一個(gè)元素,此方法等效于removeFirst()
public E pop() {
        return removeFirst();
    }

五绞旅、ArrayListLinkedList的區(qū)別

(一)從插入摆尝、刪除元素分析

對(duì)于兩者的插入、刪除操作不能片面的蓋棺定論因悲,應(yīng)視情況而定堕汞,下面以插入操作做分析(刪除操作的分析類似)
順序插入:

  • ArrayList在不擴(kuò)容的情況下順序插入速度較快,因?yàn)樵跇?gòu)造ArrayList之前已經(jīng)分配好空間晃琳,順序插入元素只是往指定內(nèi)存空間補(bǔ)個(gè)元素讯检;在需要擴(kuò)容的情況下,ArrayList的順序插入則顯得比較慢卫旱,因?yàn)榈讓有枰獔?zhí)行copy操作人灼,既耗時(shí)又耗空間。
  • LinkedList順序添加元素會(huì)教慢點(diǎn)顾翼,因?yàn)槊刻砑右粋€(gè)元素都要新new一個(gè)節(jié)點(diǎn)對(duì)象投放,并且還有執(zhí)行其他的引用賦值操作。

中間插入:

  • ArrayList在執(zhí)行中間插入的過(guò)程中耗時(shí)的是索引后面的元素copy移動(dòng)暴构,若果插入的位置越靠前則越慢跪呈,反之越快。
  • LinkedList在任何位置插入的效率基本上是一致的取逾,耗時(shí)的部分主要是定位索引(尋址),賦值部分只需修改引用苹支。

綜合以上所述:
(1)LinkedList做插入砾隅、刪除的時(shí)候,慢在尋址债蜜,快在只需要改變前后Node的引用地址晴埂。
(2)ArrayList做插入、刪除的時(shí)候寻定,慢在數(shù)組元素的批量copy儒洛,快在尋址。

所以狼速,如果待插入琅锻、刪除的元素是在數(shù)據(jù)結(jié)構(gòu)的前半段尤其是非常靠前的位置的時(shí)候向胡,LinkedList的效率將大大快過(guò)ArrayList恼蓬,因?yàn)?em>ArrayList將批量copy大量的元素;越往后僵芹,對(duì)于LinkedList來(lái)說(shuō)处硬,因?yàn)樗请p向鏈表,所以在第2個(gè)元素后面插入一個(gè)數(shù)據(jù)和在倒數(shù)第2個(gè)元素后面插入一個(gè)元素在效率上基本沒(méi)有差別拇派,但是ArrayList由于要批量copy的元素越來(lái)越少荷辕,操作速度必然追上乃至超過(guò)LinkedList凿跳。

(二)從遍歷列表分析

未完待續(xù)。疮方。控嗜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市案站,隨后出現(xiàn)的幾起案子躬审,更是在濱河造成了極大的恐慌,老刑警劉巖蟆盐,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件承边,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡石挂,警方通過(guò)查閱死者的電腦和手機(jī)博助,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)痹愚,“玉大人富岳,你說(shuō)我怎么就攤上這事≌” “怎么了窖式?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)动壤。 經(jīng)常有香客問(wèn)我萝喘,道長(zhǎng),這世上最難降的妖魔是什么琼懊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任阁簸,我火速辦了婚禮,結(jié)果婚禮上哼丈,老公的妹妹穿的比我還像新娘启妹。我一直安慰自己,他們只是感情好醉旦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布饶米。 她就那樣靜靜地躺著,像睡著了一般髓抑。 火紅的嫁衣襯著肌膚如雪咙崎。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,816評(píng)論 1 290
  • 那天吨拍,我揣著相機(jī)與錄音褪猛,去河邊找鬼。 笑死羹饰,一個(gè)胖子當(dāng)著我的面吹牛伊滋,可吹牛的內(nèi)容都是我干的碳却。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼笑旺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼昼浦!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起筒主,我...
    開(kāi)封第一講書(shū)人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤关噪,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后乌妙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體使兔,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年藤韵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了虐沥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泽艘,死狀恐怖欲险,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情匹涮,我是刑警寧澤天试,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站然低,受9級(jí)特大地震影響秋秤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脚翘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绍哎。 院中可真熱鬧来农,春花似錦、人聲如沸崇堰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)海诲。三九已至繁莹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間特幔,已是汗流浹背咨演。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚯斯,地道東北人薄风。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓饵较,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親遭赂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子循诉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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