java8基礎(chǔ)學(xué)習(xí)-lambda表達(dá)式

android studio 下配置java8環(huán)境

首先,你的java版本得是java8,在build.gradle下配置java8

compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
}

如果你的項(xiàng)目中結(jié)合了Rxjava,需要配置

jackOptions {
       enabled true
}

jack工具鏈?zhǔn)莂ndroid在6.0版本添加的編譯器,也就是說android6.0版本的代碼都是jack工具鏈編譯的,但是安卓官方開發(fā)者網(wǎng)站已經(jīng)放出blog,在以后的android studio中,開始支持java8,開始廢棄jack(具體什么時間,引用官網(wǎng)的原話:Moving forward, Java 8 language features will be natively supported by the Android build system。),但是之前使用的jack風(fēng)格的代碼依然支持,附上官網(wǎng)鏈接


Lambda表達(dá)式

要理解lambda表達(dá)式,首先要了解的是函數(shù)式接口(functional interface)。簡單來說,函數(shù)式接口是只包含一個抽象方法的接口。比如Java標(biāo)準(zhǔn)庫中的java.lang.Runnablejava.util.Comparator都是典型的函數(shù)式接口。對于函數(shù)式接口,除了可以使用Java中標(biāo)準(zhǔn)的方法來創(chuàng)建實(shí)現(xiàn)對象之外,還可以使用lambda表達(dá)式來創(chuàng)建實(shí)現(xiàn)對象。這可以在很大程度上簡化代碼的實(shí)現(xiàn)。在使用lambda表達(dá)式時,只需要提供形式參數(shù)和方法體。由于函數(shù)式接口只有一個抽象方法,所以通過lambda表達(dá)式聲明的方法體就肯定是這個唯一的抽象方法的實(shí)現(xiàn),而且形式參數(shù)的類型可以根據(jù)方法的類型聲明進(jìn)行自動推斷。
在工作中創(chuàng)建一個線程的寫法如下:

/**
demo1
**/
public void runThread() {
    new Thread(new Runnable() {
        public void run() {
            System.out.println("test");
        }
    }).start();
}

java8中l(wèi)ambda表達(dá)式一般格式

(argument) -> {body}

argument表示的是方法中的形式參數(shù),如果沒有直接放空,后面的body是方法體
所以demo1中的代碼可以簡化如下

/**
demo2
**/
public void runThread() {
    new Thread(
         () -> {System.out.println("test");}
    ).start();
}

方法體總只有一句代碼所以可以繼續(xù)簡化

/**
demo3
**/
public void runThread() {
    new Thread(
         () -> System.out.println("test");
    ).start();
}

下面是一些常見的lambda表達(dá)式,可以加上參數(shù)類型

(int a, int b) -> {  return a + b; }
() -> System.out.println("Hello World");
(String s) -> { System.out.println(s); }
() -> 42
() -> { return 3.1415 };
a -> return a * a; // 形式參數(shù)中只有a

你也可以自己編寫函數(shù)式接口

@FunctionalInterface
public interface Annimal {
    public abstract void play();
}

@FunctionalInterface是 Java 8 新加入的一種接口,用于指明該接口類型聲明是根據(jù) Java 語言規(guī)范定義的函數(shù)式接口。Java 8 還聲明了一些 Lambda 表達(dá)式可以使用的函數(shù)式接口,當(dāng)你注釋的接口不是有效的函數(shù)式接口時,可以使用 @FunctionalInterface 解決編譯層面的錯誤。
另外,在java8中接口支持方法的實(shí)現(xiàn),對函數(shù)式接口并不影響

@FunctionalInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public interface Annimal {
    public abstract void play();
    default void fly(){
      System.out.println("fly");
    }
    static void eat(){
      System.out.println("eat");
    }
}

上面的書寫并不會編譯報錯,也是符合規(guī)范的,但是如果添加普通的方法就會報錯,所以最好在接口上使用注解@FunctionalInterface進(jìn)行聲明,以免團(tuán)隊的其他人員錯誤地往接口中添加新的方法。

Lambda 表達(dá)式與匿名類的區(qū)別

使用匿名類與 Lambda 表達(dá)式的一大區(qū)別在于關(guān)鍵詞的使用。對于匿名類,關(guān)鍵詞 this
解讀為匿名類,而對于 Lambda 表達(dá)式,關(guān)鍵詞 this
解讀為寫就 Lambda 的外部類。
Lambda 表達(dá)式與匿名類的另一不同在于兩者的編譯方法。Java 編譯器編譯 Lambda 表達(dá)式并將他們轉(zhuǎn)化為類里面的私有函數(shù),它使用 Java 7 中新加的 invokedynamic
指令動態(tài)綁定該方法,關(guān)于 Java 如何將 Lambda 表達(dá)式編譯為字節(jié)碼,Tal Weiss 寫了一篇很好的文章。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容