国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Rumah 類庫下載 java類庫 Java Lambda表達(dá)式初探

Java Lambda表達(dá)式初探

Oct 09, 2016 am 10:24 AM

Java Lambda表達(dá)式初探

前言

本文受啟發(fā)于Trisha Gee在JavaOne 2016的主題演講Refactoring to Java 8。

Java 8已經(jīng)發(fā)行兩年多,但很多人仍然在使用JDK7。對企業(yè)來說,技術(shù)上謹(jǐn)慎未必是壞事,但對個人學(xué)習(xí)而言,不去學(xué)習(xí)新技術(shù)就很可能被技術(shù)拋棄。Java 8一個重要的變更是引入Lambda表達(dá)式(lambda expression),這聽起來似乎很牛,有種我雖然不知道Lambda表達(dá)式是什么,但我仍然覺得很厲害的感覺。不要怕,具體到語言層面上Lambda表達(dá)式不過是一種新的語法而已,有了它,Java將開啟函數(shù)式編程的大門。

為什么需要Lambda表達(dá)式

不要糾結(jié)什么是Lambda表達(dá)式、什么是函數(shù)式編程。先來看一下Java 8新的語法特性帶來的便利之處,相信你會過目不忘的。

在有Lambda表達(dá)式之前,要新建一個線程,需要這樣寫:

new Thread(new Runnable(){    @Override
    public void run(){
        System.out.println("Thread run()");
    }
}).start();

有Lambda表達(dá)式之后,則可以這樣寫:

new Thread(
        () -> System.out.println("Thread run()")
).start();

正如你所見,之前無用的模板代碼不見了!如上所示,Lambda表達(dá)式一個常見的用法是取代(某些)匿名內(nèi)部類,但Lambda表達(dá)式的作用不限于此。

Lambda表達(dá)式的原理

剛接觸Lambda表達(dá)式可能覺得它很神奇:不需要聲明類或者方法的名字,就可以直接定義函數(shù)。但其實(shí)這只是編譯器給我們提供的一個小把戲,背后的原理并不難理解。下面是Lambda表達(dá)式幾種可能的書寫形式:

Runnable run = () -> System.out.println("Hello World");// 1ActionListener listener = event -> System.out.println("button clicked");// 2Runnable multiLine = () -> {// 3
    System.out.println("Hello ");
    System.out.println("World");
};
BinaryOperator<Long> add = (Long x, Long y) -> x + y;// 4BinaryOperator<Long> addImplicit = (x, y) -> x + y;// 5

通過上例可以發(fā)現(xiàn):

Lambda表達(dá)式是有類型的,賦值操作的左邊就是類型。Lambda表達(dá)式的類型實(shí)際上是對應(yīng)接口的類型。

Lambda表達(dá)式可以包含多行代碼,需要用大括號把代碼塊括起來,就像寫函數(shù)體那樣。

大多數(shù)時候,Lambda表達(dá)式的參數(shù)表可以省略類型,就像代碼2和5那樣。這得益于javac的類型推導(dǎo)機(jī)制,編譯器可以根據(jù)上下文推導(dǎo)出類型信息。

實(shí)際上每個Lambda表達(dá)式都是原來匿名內(nèi)部類的簡寫形式,該內(nèi)部類實(shí)現(xiàn)了某個函數(shù)接口(Functional Interface)。所謂函數(shù)接口是指*添加了@FunctionalInterface標(biāo)注,并且內(nèi)部只有一個接口函數(shù)的接口*。Java是強(qiáng)類型語言,無論有沒有顯式指明,每個變量和對象都必須有明確的類型,沒有顯式指定的時候編譯器會嘗試確定類型。Lambda表達(dá)式的類型就是對應(yīng)函數(shù)接口的類型。

Lambda表達(dá)式和Stream

Lambda表達(dá)式的另一個重要用法,是和Stream一起使用。Stream is a sequence of elements supporting sequential and parallel aggregate operations。Stream就是一組元素的序列,支持對這些元素進(jìn)行各種操作,而這些操作是通過Lambda表達(dá)式指定的。可以把Stream看作Java Collection的一種視圖,就像迭代器是容器的一種視圖那樣(但Stream不會修改容器中的內(nèi)容)。下面例子展示了Stream的常見用法。

例子1

假設(shè)需要從一個字符串列表中選出以數(shù)字開頭的字符串并輸出,Java 7之前需要這樣寫:

List<String> list = Arrays.asList("1one", "two", "three", "4four");for(String str : list){    if(Character.isDigit(str.charAt(0))){
        System.out.println(str);
    }
}

而Java 8就可以這樣寫:

List<String> list = Arrays.asList("1one", "two", "three", "4four");
list.stream()// 1.得到容器的Steam
    .filter(str -> Character.isDigit(str.charAt(0)))// 2.選出以數(shù)字開頭的字符串
    .forEach(str -> System.out.println(str));// 3.輸出字符串

上述代碼首先1. 調(diào)用List.stream()方法得到容器的Stream,2. 然后調(diào)用filter()方法過濾出以數(shù)字開頭的字符串,3. 最后調(diào)用forEach()方法輸出結(jié)果。

使用Stream有兩個明顯的好處:

減少了模板代碼,只用Lambda表達(dá)式指明所需操作,代碼語義更加明確、便于閱讀。

將外部迭代改成了Stream的內(nèi)部迭代,方便了JVM本身對迭代過程做優(yōu)化(比如可以并行迭代)。

例子2

假設(shè)需要從一個字符串列表中,選出所有不以數(shù)字開頭的字符串,將其轉(zhuǎn)換成大寫形式,并把結(jié)果放到新的集合當(dāng)中。Java 8書寫的代碼如下:

List<String> list = Arrays.asList("1one", "two", "three", "4four");
Set<String> newList =
        list.stream()// 1.得到容器的Stream
        .filter(str -> !Character.isDigit(str.charAt(0)))// 2.選出不以數(shù)字開頭的字符串
        .map(String::toUpperCase)// 3.轉(zhuǎn)換成大寫形式
        .collect(Collectors.toSet());// 4.生成結(jié)果集

上述代碼首先1. 調(diào)用List.stream()方法得到容器的Stream,2. 然后調(diào)用filter()方法選出不以數(shù)字開頭的字符串,3. 之后調(diào)用map()方法將字符串轉(zhuǎn)換成大寫形式,4. 最后調(diào)用collect()方法將結(jié)果轉(zhuǎn)換成Set。這個例子還向我們展示了方法引用(method references,代碼中標(biāo)號3處)以及收集器(Collector,代碼中標(biāo)號4處)的用法,這里不再展開說明。

通過這個例子我們看到了Stream鏈?zhǔn)讲僮?,即多個操作可以連成一串。不用擔(dān)心這會導(dǎo)致對容器的多次迭代,因?yàn)椴皇敲總€Stream的操作都會立即執(zhí)行。Stream的操作分成兩類,一類是中間操作(intermediate operations),另一類是結(jié)束操作(terminal operation),只有結(jié)束操作才會導(dǎo)致真正的代碼執(zhí)行,中間操作只會做一些標(biāo)記,表示需要對Stream進(jìn)行某種操作。這意味著可以在Stream上通過關(guān)聯(lián)多種操作,但最終只需要一次迭代。如果你熟悉Spark RDD,對此應(yīng)該并不陌生。

結(jié)語

Java 8引入Lambda表達(dá)式,從此打開了函數(shù)式編程的大門。如果你之前不了解函數(shù)式編程,不必糾結(jié)于這個概念。編程過程中簡潔明了的書寫形式以及強(qiáng)大的Stream API會讓你很快熟悉Lambda表達(dá)式的。

本文只對Java Lambda表達(dá)式的基本介紹,希望能夠激發(fā)讀者對Java函數(shù)式編程的興趣。如果本文能夠讓你覺得Lambda表達(dá)式很好玩,函數(shù)式編程很有趣,并產(chǎn)生了進(jìn)一步學(xué)習(xí)的欲望,那就再好不過了。文末參考文獻(xiàn)中列出了一些有用的資源。


參考文獻(xiàn)

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html
http://www.slideshare.net/trishagee/refactoring-to-java-8-devoxx-uk
《Java 8函數(shù)式編程 [英]沃伯頓》
https://www.oracle.com/javaone/speakers.html#gee


Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial PHP
1502
276