java8(二)lambda表達(dá)式手把手學(xué)習(xí)

Lambda可以讓你簡單的傳遞一個行為或者代碼肠套「停可以把lambda看作是匿名函數(shù)陵像,是沒有聲明名稱的方法,但和匿名類一樣寇壳,也可以作為參數(shù)傳遞給一個方法醒颖。

可以把Lambda表達(dá)式理解為:簡潔地表示可傳遞的匿名函數(shù)的一種方式:它沒有名稱,但它有參數(shù)列表壳炎、函數(shù)主體泞歉、返回類型,可能還有一個可以拋出的異常列表匿辩。

一腰耙、在哪里使用lambda?

1.1 函數(shù)式接口

函數(shù)式接口就是只定義一個抽象方法的接口铲球。

Lambda表達(dá)式允許你直接以內(nèi)聯(lián)的形式為函數(shù)式接口的抽象方法提供實現(xiàn)挺庞,并把整個表達(dá)式作為函數(shù)式接口的實例。具體來說稼病,Lambda表達(dá)式是函數(shù)是接口的具體實現(xiàn)的實例选侨。

通過匿名內(nèi)部類也可以完成同樣的事情,但是比較笨拙:需要提供一個實現(xiàn)溯饵,然后在直接內(nèi)聯(lián)將它的實現(xiàn)實例化侵俗。如下面的例子所示,可以清楚地看到lambda的簡潔:

public class TestLambdaAndAnonymity {
    /**
     * 執(zhí)行方法
     * @param r
     */
    public static void process(Runnable r){
        r.run();
    }
    
    public static void main(String[] args) {
        // 使用匿名類
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("this is r1");
            }
        };

        // 使用Lambda
        Runnable r2 = ()-> System.out.println("this is r2");
        
        process(r1);
        process(r2);
        // 直接將lambda作為參數(shù)傳遞
        process(()-> System.out.println("this is r3"));
    }
}

1.2 函數(shù)描述符

函數(shù)式接口的抽象方法的簽名基本上就是Lambda表達(dá)式的簽名丰刊。我們將這種抽象方法叫作函數(shù)描述符隘谣。

舉個例子:
Runnable 接口可以看作一個什么也不接受什么也不返回( void )的函數(shù)的簽名,因為它只有一個叫作 run 的抽象方法啄巧,這個方法什么也不接受寻歧,什么也不返回( void )。

@FunctionalInterface
public interface Runnable {

    public abstract void run();
}

如上個小節(jié)的例子:“()-> System.out.println("this is r3")”秩仆, () -> void就是這個函數(shù)的簽名码泛, 代表了參數(shù)列表為空,且返回 void 的函數(shù)澄耍。這正是 Runnable 接口所代表的噪珊。

舉另一個例子晌缘, (Apple,Apple) -> int 代表接受兩個 Apple 作為參數(shù)且返回 int 的函數(shù)。

1.3 @FunctionalInterface 又是怎么回事痢站?

如果你去看看新的Java API磷箕,會發(fā)現(xiàn)函數(shù)式接口帶有 @FunctionalInterface 的標(biāo)注。這個標(biāo)注用于表示該接口會設(shè)計成一個函數(shù)式接口阵难。如果你用 @FunctionalInterface 定義了一個接口岳枷,而它卻不是函數(shù)式接口的話,編譯器將返回一個提示原因的錯誤呜叫。如下:

    @FunctionalInterface
    private interface ITest{
        void test();

        void test1();
    }
image.png

表示該接口存在多個抽象方法空繁。

@FunctionalInterface 不是必需的,但對于為此設(shè)計的接口而言朱庆,使用它是比較好的做法盛泡。

二、使用函數(shù)式接口

函數(shù)式接口定義且只定義了一個抽象方法椎工。函數(shù)式接口很有用饭于,因為抽象方法的簽名可以描述Lambda表達(dá)式的簽名蜀踏。函數(shù)式接口的抽象方法的簽名稱為函數(shù)描述符维蒙。所以為了應(yīng)用不同的Lambda表達(dá)式,你需要一套能夠描述常見函數(shù)描述符的函數(shù)式接口果覆。

Java 8的庫設(shè)計師幫你在 java.util.function 包中引入了幾個新的函數(shù)式接口颅痊。

2.1 Predicate

java.util.function.Predicate<T> 接口定義了一個名叫 test 的抽象方法,它接受泛型T 對象局待,并返回一個 boolean 斑响。

@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);
}

如下篩選華為手機(jī)的例子:

    /**
     * 手機(jī)過濾方法,參數(shù)是手機(jī)list和Predicate<T>函數(shù)
     */
    public static List<Phone> phoneFilter(List<Phone> phones, Predicate<Phone> p) {
        List<Phone> results = new ArrayList<>();
        for (Phone phone : phones) {
            if (p.test(phone)) {
                results.add(phone);
            }
        }
        return results;
    }

    // 調(diào)用篩選方法
    List<Phone> huaweiPhones = phoneFilter(list, (Phone p) -> "華為".equals(p.brand));

關(guān)于其中的and钳榨、or等方法此小節(jié)先不考慮舰罚。

2.2 Consumer

java.util.function.Consumer<T> 定義了一個名叫 accept 的抽象方法,它接受泛型 T的對象薛耻,沒有返回( void )营罢。你如果需要訪問類型 T 的對象,并對其執(zhí)行某些操作饼齿,就可以使用這個接口饲漾。

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

如下例子,分別打印每個值:

public class TestConsumer {

    public static void main(String[] args) {
        forEach(Arrays.asList(1, 2, 3, 4, 5), (Integer i) -> System.out.println(i));
    }

    public static <T> void forEach(List<T> list, Consumer<T> c) {
        for (T t : list) {
            c.accept(t);
        }

    }
}

2.3 Function

java.util.function.Function<T, R> 接口定義了一個叫作 apply 的方法缕溉,它接受一個泛型 T 的對象考传,并返回一個泛型 R 的對象。如果你需要定義一個Lambda证鸥,將輸入對象的信息映射到輸出僚楞,就可以使用這個接口勤晚。

@FunctionalInterface
public interface Function<T, R> {

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);

如下所示,將String列表的長度映射到Integer列表:

    public static <T, R> List<R> map(List<T> list, Function<T, R> function) {
        List<R> results = new ArrayList<>();
        for (T t : list) {
            results.add(function.apply(t));
        }
        return results;
    }

    public static void main(String[] args) {
        List<Integer> map = map(Arrays.asList("Tom", "Jerry", "XiaoMing"), (String s) -> s.length());
        System.out.println(map);
    }

以上簡單介紹了三種函數(shù)式接口的使用方式泉褐。

2.4 帶有數(shù)據(jù)類型的函數(shù)式接口

Java類型要么是引用類型(比如 Byte 运翼、 Integer 、 Object 兴枯、 List )血淌,要么是原始類型(比如 int 、 double 财剖、 byte 悠夯、 char )。但是泛型(比如 Consumer<T> 中的 T )只能綁定到引用類型躺坟。這是由泛型內(nèi)部的實現(xiàn)方式造成的沦补。

因此,在Java里有一個將原始類型轉(zhuǎn)換為對應(yīng)的引用類型的機(jī)制咪橙。這個機(jī)制叫作裝箱(boxing)夕膀。相反的操作,也就是將引用類型轉(zhuǎn)換為對應(yīng)的原始類型美侦,叫作拆箱(unboxing)产舞。Java還有一個自動裝箱機(jī)制來幫助程序員執(zhí)行這一任務(wù):裝箱和拆箱操作是自動完成的。

如下所示就是一個裝箱過程菠剩,將int類型裝箱成Integer類型:

List<Integer> list = new ArrayList<>();
for (int i = 300; i < 400; i++){
    list.add(i);
}

但這在性能方面是要付出代價的易猫。裝箱后的值本質(zhì)上就是把原始類型包裹起來,并保存在堆里具壮。因此准颓,裝箱后的值需要更多的內(nèi)存,并需要額外的內(nèi)存搜索來獲取被包裹的原始值棺妓。

減少裝箱拆箱是有必要的攘已!

java8為了減少這樣的問題,針對不同的接口函數(shù)提供專門的版本怜跑,用來避免自動裝箱操作样勃。

如下舉例1000萬次的循環(huán),分別比較裝箱和不裝箱的耗時有多大:

    public static void main(String[] args) throws InterruptedException {
        Long current = System.currentTimeMillis();

        // 非裝箱
        IntPredicate intPredicate = (int i) -> i % 3 == 0;
        CompletableFuture.runAsync(() -> {
            for (int i = 0; i < 10000000; i++) {
                intPredicate.test(RandomUtil.randomInt(100000));
            }
            System.out.println("線程名稱:IntPredicate" + Thread.currentThread().getName()+"耗時:"+ (System.currentTimeMillis() - current));
        });

        // 裝箱
        Predicate<Integer> predicate = (Integer i) -> i % 3 == 0;
        CompletableFuture.runAsync(() -> {
            for (int i = 0; i < 10000000; i++) {
                predicate.test(RandomUtil.randomInt(100000));
            }
            System.out.println("線程名稱:Predicate" + Thread.currentThread().getName()+"耗時:"+ (System.currentTimeMillis() - current));
        });

        //等待線程執(zhí)行完成
        Thread.sleep(1000);
    }

結(jié)果顯示妆艘,使用IntPredicate比Predicate耗時差距在50ms左右:

線程名稱:IntPredicateForkJoinPool.commonPool-worker-1耗時:143
線程名稱:PredicateForkJoinPool.commonPool-worker-2耗時:194

一般來說彤灶,針對特殊類型的函數(shù)式接口的名稱都需要加上對應(yīng)的原始類型的前綴。

下面歸納常用函數(shù)式接口:

函數(shù)式接口 函數(shù)式描述符 原始類型特化
Predicate<T> T->boolean IntPredicate
LongPredicate
DoublePredicate
Consumer<T> T->void IntConsumer
LongConsumer
DoubleConsumer
Function<T,R> T->R IntFunction<R>
IntToDoubleFunction
IntToLongFunction
LongFunction<R>
LongToDoubleFunction
LongToIntFunction
DoubleFunction<R>
ToIntFunction<T>
ToDoubleFunction<T>
ToLongFunction<T>
Supplier<T> ()-T BooleanSupplier,IntSupplier
LongSupplier
DoubleSupplier
UnaryOperator<T> T->T IntUnaryOperator
LongUnaryOperator
DoubleUnaryOperator
BinaryOperator<T> (T,T)->T IntBinaryOperator
LongBinaryOperator
DoubleBinaryOperator
BiPredicate<L,R> (L,R)->boolean
BiConsumer<T,U> (T,U)->void ObjIntConsumer<T>
ObjLongConsumer<T>
ObjDoubleConsumer<T>
BiFunction<T,U,R> (T,U)->R ToIntBiFunction<T,U>
ToLongBiFunction<T,U>
ToDoubleBiFunction<T,U>

三批旺、使用局部變量

Lambda可以沒有限
制地捕獲(也就是在其主體中引用)實例變量和靜態(tài)變量幌陕。但局部變量必須顯式聲明為 final ,或事實上是 final 汽煮。換句話說搏熄,Lambda表達(dá)式只能捕獲指派給它們的局部變量一次棚唆。(注:捕獲實例變量可以被看作捕獲最終局部變量 this 。)

如下代碼將會出現(xiàn)變異錯誤心例,因為portBynber變了兩次:

        int portNumber = 1337;
        Runnable r = () -> System.out.println(portNumber);
        portNumber = 31337;
image.png

3.1 限制局部變量的原因宵凌?

1)實例變量和局部變量背后的實現(xiàn)有一個關(guān)鍵不同。實例變量都存儲在堆中止后,而局部變量則保存在棧上瞎惫。

如果Lambda可以直接訪問局部變量,而且Lambda是在一個線程中使用的译株,則使用Lambda的線程瓜喇,可能會在分配該變量的線程將這個變量收回之后,去訪問該變量歉糜。

因此乘寒,Java在訪問自由局部變量時,實際上是在訪問它的副本匪补,而不是訪問原始變量伞辛。

如果局部變量僅僅賦值一次那就沒有什么區(qū)別了。

2)這一限制不鼓勵你使用改變外部變量的典型命令式編程模式夯缺。

這種模式會阻礙很容易做到的并行處理蚤氏,在java8當(dāng)中使用的函數(shù)式編程可以很輕易的做到并行處理,而傳統(tǒng)的命令式編程卻需要自己去實現(xiàn)多線程與數(shù)據(jù)的合并喳逛。

四瞧捌、方法引用

4.1 方法引用簡介

方法引用是某些Lambda的快捷寫法。讓你可以重復(fù)使用現(xiàn)有的方法定義润文,并像Lambda一樣傳遞它們。

當(dāng)你需要使用方法引用時殿怜,目標(biāo)引用放在分隔符 :: 前典蝌,方法的名稱放在后面。如下面的例子:

Apple::getWeight

Apple::getWeight 就是引用了 Apple 類中定義的方法 getWeight头谜,方法引用就是Lambda表達(dá)式 (Apple a) -> a.getWeight() 的快捷寫法骏掀。

你可以把方法引用看作針對僅僅涉及單一方法的Lambda的語法糖,因為你表達(dá)同樣的事情時要寫的代碼更少了柱告。

4.2 構(gòu)建方法引用

方法引用主要有三類:
1)指向靜態(tài)方法的方法引用
如下所示截驮,指向靜態(tài)方法parseInt。

    public static void main(String[] args) {
        //靜態(tài)方法引用际度,parseInt
        Function<String, Integer> function = Integer::parseInt;
        Integer apply = function.apply("100");
        System.out.println(apply);
    }

2)指向任意類型實例方法的方法引用
如下所示葵袭,指向String的length方法

        //指向任意實例類型方法
        Function<String,Integer> function1 = String::length;
        Integer hello_world = function1.apply("hello world");
        System.out.println(hello_world);

可以這樣理解這句話:你在引用一個對象的方法,而這個對象本身是Lambda的一個參數(shù)乖菱。

3)指向現(xiàn)有實例對象的方法的方法引用
如下所示:

    @Data
    static class Student{
        private String name;
        private Integer age;

        public Student(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    }

        //指向現(xiàn)有對象的方法
        Student student = new Student("Jack",10);
        Supplier<String> supplier = student::getName;
        String s = supplier.get();
        System.out.println(s);

與第二條不同坡锡,這個方法引用的對象時外部已經(jīng)存在的對象蓬网,如上述例子中的student。

4.3 構(gòu)造函數(shù)引用

對于一個現(xiàn)有構(gòu)造函數(shù)鹉勒,你可以利用它的名稱和關(guān)鍵字 new 來創(chuàng)建它的一個引用:ClassName::new 帆锋。它的功能與指向靜態(tài)方法的引用類似。

有如下實體類:

    @Data
    static class Student {
        private String name;
        private Integer age;
        private String address;

        public Student() {
        }

        public Student(String name) {
            this.name = name;
        }

        public Student(String name, Integer age) {
            this.name = name;
            this.age = age;
        }

        public Student(String name, Integer age, String address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }
    }

實例:

    /**
     * description: 自定義三個參數(shù)的接口

     * @return:
     * @author: weirx
     * @time: 2021/10/19 18:03
     */
    interface ThreeParamsFunction<T, U, P, R> {
        R apply(T t, U u, P p);
    }

    public static void main(String[] args) {
        // 無構(gòu)造參數(shù) ()->new Student() 轉(zhuǎn)化成 Student::new
        Supplier<Student> supplier = Student::new;
        Student student = supplier.get();
        // 一個構(gòu)造參數(shù) (name)->new Student(name) 轉(zhuǎn)化成 Student::new
        Function<String, Student> function = Student::new;
        function.apply("JACK");
        // 兩個構(gòu)造參數(shù) (name,age)->new Student(name,age) 轉(zhuǎn)化成 Student::new
        BiFunction<String, Integer, Student> biFunction = Student::new;
        biFunction.apply("JACK", 10);
        // 三個構(gòu)造參數(shù),沒有提供三個構(gòu)造參數(shù)的禽额,需要自己寫個接口
        // (name,age,address)->new Student(name,age,address) 轉(zhuǎn)化成 Student::new
        ThreeParamsFunction<String, Integer, String, Student> threeParamsFunction = Student::new;
        threeParamsFunction.apply("JACK", 10, "Haerbin");
    }

五锯厢、實戰(zhàn)

使用List的sort方法對蘋果進(jìn)行排序:

void sort(Comparator<? super E> c)

5.1 傳遞代碼

根據(jù)上面的sort方法構(gòu)成,我們需要一個Comparator對象對蘋果進(jìn)行比較脯倒。在沒有java8之前哲鸳,我們需要這樣做,傳遞代碼的方式

import lombok.Data;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @description: 使用List的sort方法盔憨,對蘋果進(jìn)行排序
 * @author:weirx
 * @date:2021/10/20 9:44
 * @version:3.0
 */
public class TestLambda {

    @Data
    static class Apple {
        private Integer weight;

        public Apple(Integer weight) {
            this.weight = weight;
        }
    }

    /**
     * 自定義一個比較類徙菠,實現(xiàn)Comparator接口
     */
    public static class CompareApple implements Comparator<Apple> {

        @Override
        public int compare(Apple o1, Apple o2) {
            return o1.getWeight().compareTo(o2.getWeight());
        }
    }

    public static void main(String[] args) {
        List<Apple> apples = Arrays.asList(
                new Apple(10), new Apple(19), new Apple(9), new Apple(22));
        apples.sort(new CompareApple());
    }
}

5.2 匿名類

匿名類實現(xiàn)接口,重寫compare方法郁岩,不需要單獨寫實現(xiàn)類了

import lombok.Data;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @description: 使用List的sort方法婿奔,對蘋果進(jìn)行排序
 * @author:weirx
 * @date:2021/10/20 9:44
 * @version:3.0
 */
public class TestLambda {

    @Data
    static class Apple {
        private Integer weight;

        public Apple(Integer weight) {
            this.weight = weight;
        }
    }
    
    public static void main(String[] args) {
        List<Apple> apples = Arrays.asList(
                new Apple(10), new Apple(19), new Apple(9), new Apple(22));
        // 匿名類實現(xiàn)接口,重寫compare方法
        apples.sort(new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return o1.getWeight().compareTo(o2.getWeight());
            }
        });
    }
}

5.3 使用lambda表達(dá)式

這一步將上面的匿名類轉(zhuǎn)換成了lambda表達(dá)式问慎,下面不寫多余代碼了:

    public static void main(String[] args) {
        List<Apple> apples = Arrays.asList(
                new Apple(10), new Apple(19), new Apple(9), new Apple(22));
        // lambda表達(dá)式萍摊,替換匿名類
        apples.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()));
    }

在Comparator中有一個靜態(tài)輔助方法comparing,其參數(shù)是傳遞一個Funtion<T>如叼,在方法內(nèi)部進(jìn)行了比較:

    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }

所以最終會變成如下的使用方式:

    public static void main(String[] args) {
        List<Apple> apples = Arrays.asList(
                new Apple(10), new Apple(19), new Apple(9), new Apple(22));
        // lambda表達(dá)式冰木,替換匿名類
        apples.sort(Comparator.comparing((Apple a) -> a.getWeight()));
    }

5.4 方法引用

最簡潔的實現(xiàn)方式如下所示:

import lombok.Data;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @description: 使用List的sort方法,對蘋果進(jìn)行排序
 * @author:weirx
 * @date:2021/10/20 9:44
 * @version:3.0
 */
public class TestLambda {

    @Data
    static class Apple {
        private Integer weight;

        public Apple(Integer weight) {
            this.weight = weight;
        }
    }

    public static void main(String[] args) {
        List<Apple> apples = Arrays.asList(
                new Apple(10), new Apple(19), new Apple(9), new Apple(22));
        // 方法引用笼恰,替換lambda
        apples.sort(Comparator.comparing((Apple::getWeight)));
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末踊沸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子社证,更是在濱河造成了極大的恐慌逼龟,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件追葡,死亡現(xiàn)場離奇詭異腺律,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)宜肉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門匀钧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谬返,你說我怎么就攤上這事之斯±哦梗” “怎么了统捶?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵蒿讥,是天一觀的道長挂绰。 經(jīng)常有香客問我,道長项乒,這世上最難降的妖魔是什么啰劲? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮檀何,結(jié)果婚禮上蝇裤,老公的妹妹穿的比我還像新娘。我一直安慰自己频鉴,他們只是感情好栓辜,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著垛孔,像睡著了一般藕甩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上周荐,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天狭莱,我揣著相機(jī)與錄音,去河邊找鬼概作。 笑死腋妙,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的讯榕。 我是一名探鬼主播骤素,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼愚屁!你這毒婦竟也來了济竹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤集绰,失蹤者是張志新(化名)和其女友劉穎规辱,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體栽燕,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年改淑,在試婚紗的時候發(fā)現(xiàn)自己被綠了碍岔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡朵夏,死狀恐怖蔼啦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仰猖,我是刑警寧澤捏肢,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布奈籽,位于F島的核電站,受9級特大地震影響鸵赫,放射性物質(zhì)發(fā)生泄漏衣屏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一辩棒、第九天 我趴在偏房一處隱蔽的房頂上張望狼忱。 院中可真熱鬧,春花似錦一睁、人聲如沸钻弄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窘俺。三九已至,卻和暖如春复凳,著一層夾襖步出監(jiān)牢的瞬間瘤泪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工染坯, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留均芽,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓单鹿,卻偏偏與公主長得像掀宋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子仲锄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

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