JDK8 流與λ表達(dá)式

λ表達(dá)式

什么是λ表達(dá)式

λ表達(dá)式有三部分組成:參數(shù)列表蜜托,箭頭(->)抄囚,以及一個(gè)表達(dá)式或者語(yǔ)句塊霉赡。

public int add(int x, int y) {
    return x + y;
}

轉(zhuǎn)換為λ表達(dá)式

(int x, int y) -> x + y;

去除參數(shù)類型

(x, y) -> x + y;

無(wú)參 以及 只有一個(gè)參數(shù)

() -> { System.out.println("Hello Lambda!"); 
c -> { return c.size(); }

λ表達(dá)式的類型

λ表達(dá)式可以被當(dāng)做是一個(gè)Object(注意措辭)。λ表達(dá)式的類型幔托,叫做“目標(biāo)類型(target type)”穴亏。λ表達(dá)式的目標(biāo)類型是“函數(shù)接口(functional interface)”,這是Java8新引入的概念重挑。它的定義是:一個(gè)接口嗓化,如果只有一個(gè)顯式聲明的抽象方法,那么它就是一個(gè)函數(shù)接口谬哀。一般用@FunctionalInterface標(biāo)注出來(lái)(也可以不標(biāo))刺覆。舉例如下:

@FunctionalInterface
public interface Runnable{
    void run(); 
}
    
public interface Callable<V>{
    V call() throws Exception; 
}
       
public interface Comparator<T>{
    int compare(T o1, T o2); boolean equals(Object obj); 
}

所以 可以定義

Runnable r1 = () -> {System.out.println("Hello Lambda!");};

思考:可否定義 Object o = () -> {System.out.println("Hello Lambda!");};

JDK常用的預(yù)定義接口函數(shù)

//入?yún)門(mén),返回R
@FunctionalInterface
public interface Function<T, R> {  
    R apply(T t);
}

//入?yún)門(mén)史煎,無(wú)返回值
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

//無(wú)入?yún)⑶迹祷豑(通常配合構(gòu)造方法)
@FunctionalInterface
public interface Supplier<T> {
    T get();
}

//入?yún)門(mén),返回值為boolean
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

//入?yún)門(mén),U篇梭,返回值為R 類似還有BiConsumer等
@FunctionalInterface
public interface BiFunction<T, U> {
    R accept(T t, U u);
}

方法引用

方法引用讓開(kāi)發(fā)者可以直接引用現(xiàn)存的方法氢橙、Java類的構(gòu)造方法或者實(shí)例對(duì)象。方法引用和Lambda表達(dá)式配合使用恬偷,使得java類的構(gòu)造方法看起來(lái)緊湊而簡(jiǎn)潔悍手,沒(méi)有很多復(fù)雜的模板代碼。

public static class Car {
    public static Car create( final Supplier<Car> supplier ) {
        return supplier.get();
    }              
        
    public static void collide( final Car car ) {
        System.out.println( "Collided " + car.toString() );
    }
        
    public void follow( final Car another ) {
        System.out.println( "Following the " + another.toString() );
    }
        
    public void repair() {   
        System.out.println( "Repaired " + this.toString() );
    }
}

第一種方法引用的類型是構(gòu)造器引用,語(yǔ)法是Class::new坦康,或者更一般的形式:Class<T>::new竣付。注意:這個(gè)構(gòu)造器沒(méi)有參數(shù)。

Car car = Car.create(Car::new);
List<Car> cars = Arrays.asList(car);

第二種方法引用的類型是靜態(tài)方法引用滞欠,語(yǔ)法是Class::static_method卑笨。注意:這個(gè)方法接受一個(gè)Car類型的參數(shù)。

cars.forEach(Car::collide);

第三種方法引用的類型是某個(gè)類的成員方法的引用仑撞,語(yǔ)法是Class::method赤兴,注意,這個(gè)方法沒(méi)有定義入?yún)ⅲ?/p>

cars.forEach(Car::repair);

第四種方法引用的類型是某個(gè)實(shí)例對(duì)象的成員方法的引用隧哮,語(yǔ)法是instance::method桶良。注意:這個(gè)方法接受一個(gè)Car類型的參數(shù):

final Car police = Car.create(Car::new);
cars.forEach(police::follow);

什么是流

Stream 不是數(shù)據(jù)結(jié)構(gòu),不保存數(shù)據(jù)沮翔,它是有關(guān)算法和計(jì)算的陨帆,就如同一個(gè)高級(jí)版本的迭代器(Iterator),單向采蚀,不可往復(fù)疲牵,數(shù)據(jù)只能遍歷一次,遍歷過(guò)一次后即用盡了榆鼠,就好比流水從面前流過(guò)纲爸,一去不復(fù)返。同時(shí)又與迭代器不同妆够,迭代器只能串行操作识啦,Stream可以并行化操作。

流的構(gòu)成

當(dāng)我們使用一個(gè)流的時(shí)候神妹,通常包括三個(gè)基本步驟:

獲取一個(gè)數(shù)據(jù)源(source)→數(shù)據(jù)轉(zhuǎn)換→執(zhí)行操作獲取想要的結(jié)果颓哮,每次轉(zhuǎn)換原有 Stream 對(duì)象不改變,返回一個(gè)新的 Stream 對(duì)象(可以有多次轉(zhuǎn)換)鸵荠,這就允許對(duì)其操作可以像鏈條一樣排列冕茅,變成一個(gè)管道
,如下圖所示蛹找。

image

常用的構(gòu)建流的方式:

  • 集合Collection
 Collection.stream()
 Collection.parallelStream()
  • 數(shù)組
Stream.of(T[] tArray)
  • 多個(gè)相同類型對(duì)象
Stream.of("chaimm","peter","john"); 

流的基本使用

常見(jiàn)操作

中間操作 無(wú)狀態(tài) map (mapToInt, flatMap 等)姨伤、filter、peek
有狀態(tài) distinct熄赡、sorted姜挺、limit、skip
終結(jié)操作 非短路 forEach彼硫、forEachOrdered炊豪、toArray凌箕、reduce、collect、min、 max仰税、 count
短路操作 anyMatch、allMatch芜壁、noneMatch、findFirst高氮、findAny

Stream中的操作可以分為兩大類:中間操作與終結(jié)操作

中間操作(Intermediate):一個(gè)流可以后面跟隨零個(gè)或多個(gè) intermediate 操作慧妄。其目的主要是打開(kāi)流,做出某種程度的數(shù)據(jù)映射/過(guò)濾剪芍,然后返回一個(gè)新的流塞淹,交給下一個(gè)操作使用。這類操作都是惰性化的(lazy)罪裹,就是說(shuō)饱普,僅僅調(diào)用到這類方法,并沒(méi)有真正開(kāi)始流的遍歷状共。中間操作又可以分為無(wú)狀態(tài)(Stateless)操作與有狀態(tài)(Stateful)操作套耕,前者是指元素的處理不受之前元素的影響;后者是指該操作只有拿到所有元素之后才能繼續(xù)下去峡继。

終結(jié)操作(Terminal):一個(gè)流只能有一個(gè) terminal 操作冯袍,當(dāng)這個(gè)操作執(zhí)行后,流就被使用“光”了鬓椭,無(wú)法再被操作颠猴。所以這必定是流的最后一個(gè)操作关划。Terminal 操作的執(zhí)行小染,才會(huì)真正開(kāi)始流的遍歷,并且會(huì)生成一個(gè)結(jié)果贮折。終結(jié)操作又可以分為短路與非短路操作裤翩,短路是指遇到某些符合條件的元素就可以得到最終結(jié)果,比如找到第一個(gè)滿足條件的元素。而非短路是指必須處理所有元素才能得到最終結(jié)果调榄。

map/flatMap

對(duì)流中的每個(gè)元素執(zhí)行一個(gè)函數(shù)踊赠,使得元素轉(zhuǎn)換成另一種類型輸出。

map 一對(duì)一 (入?yún)?Function<T, R>)

List<Person> persons = new ArrayLisy<>();
List<Long> result = persons.stream().map(x -> x.getId())
        .collect(Collectors.toList());

List<Student> result = persons.stream().map(x -> {
    Student s = new Student();
    s.setName(x.getName());
    return s;
}).collect(Collectors.toList());

flatMap 一對(duì)多 (入?yún)?Function<T, ? extends Stream>)

List<List<Person>> listAll = new ArrayList<>();

List<Person> result = listAll.stream().flatMap(x -> x.stream())
        .collect(Collectors.toList());

List<Student> result = listAll.stream().flatMap(x -> x.stream())
        .map(x -> {
            Student s = new Student();
            s.setName(x.getName());
            return s;
        }).collect(Collectors.toList());

filter

filter 對(duì)原始 Stream 進(jìn)行某項(xiàng)測(cè)試每庆,通過(guò)測(cè)試的元素被留下來(lái)生成一個(gè)新 Stream筐带。 (入?yún)?Predicate)

Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6};
Integer[] evens = Stream.of(nums).filter(n -> n%2 == 0)
        .toArray(Integer[]::new);

List<Student> result = persons.stream().filter(x -> x.getAge() < 20)
        .map(x -> {
            Student s = new Student();
            s.setName(x.getName());
            return s;
        }).collect(Collectors.toList());

peek

peek 方法我們可以拿到元素,然后做一些其他事情缤灵。(入?yún)?Consumer)

List<Long> result = persons.stream().map(x -> x.getId())
        .peek(x -> System.out.println(x))
        .collect(Collectors.toList());

Map<Long, Person> map = new HashMap<>();
List<Student> result = persons.stream()
        .filter(x -> x.getAge() < 20 )
        .peek(x -> map.put(x.getId(), x) )
        .map(x -> {
            Student s = new Student();
            s.setName(x.getName());
            return s;
        }).collect(Collectors.toList());

limit/skip

limit 返回 Stream 的前面 n 個(gè)元素伦籍,skip 則是扔掉前 n 個(gè)元素

List<Long> result = persons.stream().map(x -> x.getId())
    .limit(10).skip(3).collect(Collectors.toList());

sorted

對(duì)元素進(jìn)行排序 (入?yún)?Comparator)

List<Person> personList2 = persons.stream()
    .sorted((p1, p2) -> p1.getName().compareTo(p2.getName()))
    .collect(Collectors.toList());

forEach

對(duì)元素進(jìn)行遍歷消費(fèi) (入?yún)?Consumer)

persons.stream().sorted((p1, p2) -> p1.getName().compareTo(p2.getName()))
    .forEach(peron -> {
        System.out.println(persion.getName());
    });

collect

對(duì)元素進(jìn)行收集

List<Person> personList2 = persons.stream()
    .sorted((p1, p2) -> p1.getName().compareTo(p2.getName()))
    .collect(Collectors.toList());

List<Person> personList2 = persons.stream()
    .sorted((p1, p2) -> p1.getName().compareTo(p2.getName()))
    .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
Collectors.toMap

轉(zhuǎn)換為MAP

Map<Long, String> personIdNameMap = persons.stream()
    .collect(Collectors.toMap(Person::getId, Person::getName);

Map<Long, String> personIdNameMap = persons.stream()
    .collect(Collectors.toMap(Person::getId, Person::getName, (v1,v2)->v1);
Collectors.groupingBy

分組

Map<Integer, List<Person>> personAgeMap = persons.stream()
    .collect(Collectors.groupingBy(Person::getAge));

Map<Integer, Map<Long, Person>> personAgeMap =  persons.stream()
    .collect(Collectors.groupingBy(Person::getAge,
        Collectors.toMap(Person::getId, Function.identity())));
Collectors.collectingAndThen

收集然后處理

Map<Integer, Integer> personAgeMap =  persons.stream()
    .collect(Collectors.groupingBy(Person::getAge,
        Collectors.collectingAndThen(
            Collectors.toList(),
            list->list.size()
        )));

接口方法

接口default方法

默認(rèn)方法使得開(kāi)發(fā)者可以在不破壞兼容性的前提下蓝晒,往現(xiàn)存接口中添加新的方法,即不強(qiáng)制那些實(shí)現(xiàn)了該接口的類也同時(shí)實(shí)現(xiàn)這個(gè)新加的方法帖鸦。

默認(rèn)方法和抽象方法之間的區(qū)別在于抽象方法需要實(shí)現(xiàn)芝薇,而默認(rèn)方法不需要。接口提供的默認(rèn)方法會(huì)被接口的實(shí)現(xiàn)類繼承或者覆寫(xiě)

private interface HelloService {
    default String sayHello() { 
        return "hello"; 
    }        
}
        
private static class HelloImpl implements HelloService {
}
    
private static class HelloWorldImpl implements HelloService {
    @Override
    public String sayHello() {
        return "hello world";
    }
}

思考:為啥要加入default方法作儿?

接口static方法

private interface HelloService {
    static boolean testHello(String s) { 
        return Objects.equals(s,"hello");
    }        
}

Stream流水線解決方案

Stage(Pipeline)

java8用Stage來(lái)記錄Stream的中間操作洛二,很多Stream操作會(huì)需要一個(gè)回調(diào)函數(shù)(Lambda表達(dá)式),因此一個(gè)完整的操作是<數(shù)據(jù)來(lái)源攻锰,操作晾嘶,回調(diào)函數(shù)>構(gòu)成的三元組。Stream中使用Stage的概念來(lái)描述一個(gè)完整的操作娶吞,并用某種實(shí)例化后的Pipeline來(lái)代表Stage变擒,然后將具有先后順序的各個(gè)Stage連到一起,就構(gòu)成了整個(gè)流水線寝志。


image

Sink

有了操作娇斑,我們需要將所有操作疊加起來(lái),讓流水線起到應(yīng)有的作用材部,java用Sink來(lái)協(xié)調(diào)相鄰Stage之間的調(diào)用關(guān)系毫缆。每個(gè)Stage必須實(shí)現(xiàn)opWrapSink方法。Sink接口的主要方法如下

方法名 作用
void begin(long size) 開(kāi)始遍歷元素之前調(diào)用該方法乐导,通知Sink做好準(zhǔn)備
void end() 所有元素遍歷完成之后調(diào)用苦丁,通知Sink沒(méi)有更多的元素了
boolean cancellationRequested() 是否可以結(jié)束操作,可以讓短路操作盡早結(jié)束
void accept(T t) 遍歷元素時(shí)調(diào)用物臂,接受一個(gè)待處理元素旺拉,并對(duì)元素進(jìn)行處理

每個(gè)Stage都會(huì)將自己的操作封裝到一個(gè)Sink里,前一個(gè)Stage只需調(diào)用后一個(gè)方法即可棵磷,并不需要知道其內(nèi)部是如何處理的蛾狗。當(dāng)然對(duì)于有狀態(tài)的操作,Sink的begin()和end()方法也是必須實(shí)現(xiàn)的仪媒。比如Stream.sorted()是一個(gè)有狀態(tài)的中間操作沉桌,其對(duì)應(yīng)的Sink.begin()方法可能創(chuàng)建一個(gè)乘放結(jié)果的容器,而accept()方法負(fù)責(zé)將元素添加到該容器算吩,最后end()負(fù)責(zé)對(duì)容器進(jìn)行排序留凭。對(duì)于短路操作,Sink.cancellationRequested()也是必須實(shí)現(xiàn)的偎巢,比如Stream.findFirst()是短路操作蔼夜,只要找到一個(gè)元素,cancellationRequested()就應(yīng)該返回true压昼,以便調(diào)用者盡快結(jié)束查找求冷。Sink的四個(gè)接口方法常常相互協(xié)作翠订,共同完成計(jì)算任務(wù)。實(shí)際上Stream API內(nèi)部實(shí)現(xiàn)的的本質(zhì)遵倦,就是如何重載Sink的這四個(gè)接口方法尽超。

map方法的主要實(shí)現(xiàn)

public final <R> Stream<R> map(Function<? super P_OUT, ? extends R> mapper) {
    Objects.requireNonNull(mapper);
    return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE,
                                 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
        @Override
        Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) {
            return new Sink.ChainedReference<P_OUT, R>(sink) {
                @Override
                public void accept(P_OUT u) {
                    downstream.accept(mapper.apply(u));
                }
            };
        }
    };
}
static abstract class ChainedReference<T, E_OUT> implements Sink<T> {
    protected final Sink<? super E_OUT> downstream;

    public ChainedReference(Sink<? super E_OUT> downstream) {
        this.downstream = Objects.requireNonNull(downstream);
    }

    @Override
    public void begin(long size) {
        downstream.begin(size);
    }

    @Override
    public void end() {
        downstream.end();
    }

    @Override
    public boolean cancellationRequested() {
        return downstream.cancellationRequested();
    }
}
// Stream.sort()方法用到的Sink實(shí)現(xiàn)
class RefSortingSink<T> extends AbstractRefSortingSink<T> {
    private ArrayList<T> list;// 存放用于排序的元素
    RefSortingSink(Sink<? super T> downstream, Comparator<? super T> comparator) {
        super(downstream, comparator);
    }
    @Override
    public void begin(long size) {
        ...
        // 創(chuàng)建一個(gè)存放排序元素的列表
        list = (size >= 0) ? new ArrayList<T>((int) size) : new ArrayList<T>();
    }
    @Override
    public void end() {
        list.sort(comparator);// 只有元素全部接收之后才能開(kāi)始排序
        downstream.begin(list.size());
        if (!cancellationWasRequested) {// 下游Sink不包含短路操作
            list.forEach(downstream::accept);// 2. 將處理結(jié)果傳遞給流水線下游的Sink
        }
        else {// 下游Sink包含短路操作
            for (T t : list) {// 每次都調(diào)用cancellationRequested()詢問(wèn)是否可以結(jié)束處理。
                if (downstream.cancellationRequested()) break;
                downstream.accept(t);// 2. 將處理結(jié)果傳遞給流水線下游的Sink
            }
        }
        downstream.end();
        list = null;
    }
    @Override
    public void accept(T t) {
        list.add(t);// 1. 使用當(dāng)前Sink包裝動(dòng)作處理t梧躺,只是簡(jiǎn)單的將元素添加到中間列表當(dāng)中
    }
}

多個(gè)Sink疊加

多個(gè)Stage組成的鏈路如圖所示似谁,那么什么時(shí)候出發(fā)執(zhí)行結(jié)束操作(Terminal Operation),一旦調(diào)用某個(gè)結(jié)束操作掠哥,就會(huì)觸發(fā)整個(gè)流水線的執(zhí)行巩踏。

final <P_IN> void copyInto(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator){
    ...
    if (!StreamOpFlag.SHORT_CIRCUIT.isKnown(getStreamAndOpFlags())) {
        wrappedSink.begin(spliterator.getExactSizeIfKnown());// 通知開(kāi)始遍歷
        spliterator.forEachRemaining(wrappedSink);// 迭代
        wrappedSink.end();// 通知遍歷結(jié)束
    }
    ...
}

元空間

永久代的消除

從JDK1.7開(kāi)始,貯存在永久代的一部分?jǐn)?shù)據(jù)已經(jīng)轉(zhuǎn)移到了Java Heap或者是Native Heap续搀。符號(hào)引用(Symbols)轉(zhuǎn)移到了native heap;字面量(interned strings)轉(zhuǎn)移到了java heap;類的靜態(tài)變量(class statics)轉(zhuǎn)移到了java heap塞琼。但永久代仍然存在于JDK7,并沒(méi)有完全的移除禁舷。在JDK1.8版本中永久帶被徹底移除彪杉。永久代的參數(shù)-XX:PermSize和-XX:MaxPermSize也被移除。該參數(shù)在JDK1.8使用會(huì)有警告

元空間

JDK1.8將類信息存儲(chǔ)在元空間中牵咙,元空間并不在虛擬機(jī)中派近,而是使用本地內(nèi)存。因此洁桌,默認(rèn)情況下渴丸,元空間的大小僅受本地內(nèi)存限制,但可以通過(guò)以下參數(shù)來(lái)指定元空間的大辛砹琛:

-XX:MetaspaceSize谱轨,初始空間大小,達(dá)到該值就會(huì)觸發(fā)垃圾收集進(jìn)行類型卸載吠谢,同時(shí)GC會(huì)對(duì)該值進(jìn)行調(diào)整:如果釋放了大量的空間土童,就適當(dāng)降低該值;如果釋放了很少的空間囊卜,那么在不超過(guò)MaxMetaspaceSize時(shí)娜扇,適當(dāng)提高該值。

-XX:MaxMetaspaceSize栅组,最大空間,默認(rèn)是沒(méi)有限制的(取決于內(nèi)存)枢析。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末玉掸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子醒叁,更是在濱河造成了極大的恐慌司浪,老刑警劉巖泊业,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異啊易,居然都是意外死亡吁伺,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)租谈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)篮奄,“玉大人,你說(shuō)我怎么就攤上這事割去】呷矗” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵呻逆,是天一觀的道長(zhǎng)夸赫。 經(jīng)常有香客問(wèn)我,道長(zhǎng)咖城,這世上最難降的妖魔是什么茬腿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮宜雀,結(jié)果婚禮上滓彰,老公的妹妹穿的比我還像新娘。我一直安慰自己州袒,他們只是感情好揭绑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著郎哭,像睡著了一般他匪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上夸研,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天邦蜜,我揣著相機(jī)與錄音,去河邊找鬼亥至。 笑死悼沈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的姐扮。 我是一名探鬼主播絮供,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼茶敏!你這毒婦竟也來(lái)了壤靶?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤惊搏,失蹤者是張志新(化名)和其女友劉穎贮乳,沒(méi)想到半個(gè)月后忧换,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡向拆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年亚茬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浓恳。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡刹缝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奖蔓,到底是詐尸還是另有隱情赞草,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布吆鹤,位于F島的核電站厨疙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏疑务。R本人自食惡果不足惜沾凄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望知允。 院中可真熱鬧撒蟀,春花似錦、人聲如沸温鸽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)涤垫。三九已至姑尺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝠猬,已是汗流浹背切蟋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留榆芦,地道東北人柄粹。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像匆绣,于是被迫代替她去往敵國(guó)和親驻右。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理犬绒,服務(wù)發(fā)現(xiàn)旺入,斷路器,智...
    卡卡羅2017閱讀 134,629評(píng)論 18 139
  • Int Double Long 設(shè)置特定的stream類型凯力, 提高性能茵瘾,增加特定的函數(shù) 無(wú)存儲(chǔ)。stream不是一...
    patrick002閱讀 1,267評(píng)論 0 0
  • 為了支持函數(shù)式編程咐鹤,Java 8引入了Lambda表達(dá)式.在Java 8中采用的是內(nèi)部類來(lái)實(shí)現(xiàn)Lambda表達(dá)式....
    光劍書(shū)架上的書(shū)閱讀 955評(píng)論 2 10
  • 簡(jiǎn)介 λ表達(dá)式(也稱為閉包)是Java 8中最大和最令人期待的語(yǔ)言改變拗秘。它允許我們將函數(shù)當(dāng)成參數(shù)傳遞給某個(gè)方法,或...
    東方靈龍閱讀 688評(píng)論 0 2
  • 自從我踏上三尺講臺(tái)的那天起祈惶,我一直站在教育工作的前沿雕旨。在工作中兢兢業(yè)業(yè),盡職盡責(zé)捧请,始終用愛(ài)心去感動(dòng)學(xué)生凡涩,讓...
    bqxlhy閱讀 185評(píng)論 2 2