Lambda 表達(dá)式,早學(xué)早理解

被公司打發(fā)去做小程序啦,剛剛還在寫Android,淚奔

Lambda 表達(dá)式


編程中提到的 Lambda 表達(dá)式,通常是在需要一個函數(shù),但是又不想費神去命名一個函數(shù)的場合下使用,也就是指匿名函數(shù)。

Lambda 允許我們把行為傳到函數(shù)里。之前把行為傳到函數(shù)里我們采用的是匿名內(nèi)部類,該方法導(dǎo)致行為最重要的方法夾雜在中間,不夠突出,詳見舉例中代碼。

//以前點擊事件,使用了匿名內(nèi)部類
mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "toast", Toast.LENGTH_LONG).show();
            }
        });

//新款Lambda 表達(dá)式,大家可以比較下上下的不同之處
mButton.setOnClickListener(view -> Toast.makeText(MainActivity.this, "toast", Toast.LENGTH_LONG).show());

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

代碼格式


Lambda 表達(dá)式的基本格式是:() -> {}

有下面三種具體表達(dá):

//(params) -> expression
//接收 x 和 y 這兩個整形參數(shù)并返回它們的和; 
(int x, int y) -> x + y

//(params) -> statement   
//不接收參數(shù),返回整數(shù) ‘42’; 
() -> 42

//(params) -> {statement}
//接收一個字符串并把它打印到控制臺,不返回值。
(String s) -> { System.out.println(s); }

文字解釋


Lambda 表達(dá)式的語法由參數(shù)列表、箭頭符號 -> 和函數(shù)體組成。函數(shù)體既可以是一個表達(dá)式,也可以是一個語句塊:

  • 表達(dá)式:表達(dá)式會被執(zhí)行然后返回執(zhí)行結(jié)果。
  • 語句塊:語句塊中的語句會被依次執(zhí)行,就像方法中的語句一樣
    • return 語句會把控制權(quán)交給匿名方法的調(diào)用者
    • break 和 continue 只能在循環(huán)中使用
    • 如果函數(shù)體有返回值,那么函數(shù)體內(nèi)部的每一條路徑都必須有返回值

Lambda 表達(dá)式也會經(jīng)常出現(xiàn)在嵌套環(huán)境中,比如說作為方法的參數(shù)。為了使 lambda 表達(dá)式在這些場景下盡可能簡潔,我們?nèi)コ瞬槐匾姆指舴?。不過在某些情況下我們也可以把它分為多行,然后用括號包起來,就像其它普通表達(dá)式一樣。


FileFilter java = (File f) -> f.getName().endsWith("*.java");
String user = doPrivileged(() -> System.getProperty("user.name"));
new Thread(() -> {
  connectToService();
  sendNotification();
}).start();

具體案例


方法引用(關(guān)鍵字 ::)


簡單來說,方法引用就是 Lambda 表達(dá)式的一種簡寫。當(dāng)你創(chuàng)建一個 Lambda 表達(dá)式時,你創(chuàng)建了一個匿名方法并提供方法體,但你使用方法引用時,你只需要提供已經(jīng)存在的方法的名字,它本身已經(jīng)包含方法體。

做一個簡單的解釋,對集合進(jìn)行排序,使用了Comparator的匿名內(nèi)部類寫法

public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(2);
        list.add(1);
    
        Collections.sort(list,new  Comparator<Integer>(){
            @Override
            public int compare(Integer a, Integer b) {
                return a - b;
            }
        });
    }

//用Lambda 進(jìn)行表示
Collections.sort(list, (a, b) -> a - b);

//使用Lamabda 的方法引用,可以讓匿名內(nèi)部類Comparator中方法的兩個參數(shù)和Integer類中compare方法的兩個參數(shù)自動對應(yīng)起來,是不是簡潔明了呢。
Collections.sort(list, Integer::compare);

方法引用的種類(Kinds of method references)

  • 靜態(tài)方法引用:ClassName::methodName
  • 實例上的實例方法引用:instanceReference::methodName
  • 超類上的實例方法引用:super::methodName
  • 類型上的實例方法引用:ClassName::methodName
  • 構(gòu)造方法引用:Class::new
  • 數(shù)組構(gòu)造方法引用:TypeName[]::new
  • 對于靜態(tài)方法引用,我們需要在類名和方法名之間加入 :: 分隔符,例如 Integer::sum

使用 Lambda 的好處


  • Lambda 表達(dá)式不需要每次都要被實例化,對于 Java 來說,帶來巨大的好處。不像實例化匿名類,對內(nèi)存的影響可以降到最小。
  • Lambda 表達(dá)式不需要拷貝變量到它的運行環(huán)境中,從而 Lambda 表達(dá)式被當(dāng)做是一個真正的方法來對待,而不是一個類的實例 。
  • 因為是復(fù)制,變量必須聲明為 final 類型,以保證在獲取和使用時不會被改變。Java 使用了優(yōu)雅的方式保證了變量不會被更新,所以我們不用顯式地把變量加上 final 修飾。
  • Lambda 表達(dá)式函數(shù)體適合小型 Lambda 表達(dá)式,它消除了 return 關(guān)鍵字,使得語法更加簡潔。
  • Lambda 表達(dá)式取代了匿名內(nèi)部類,取消了模板,允許通過函數(shù)式風(fēng)格編寫代碼,使代碼的可讀性更高,如果不想看不懂大佬的代碼的話,趕緊學(xué)起來吧。

參考


http://m.itdecent.cn/p/f569c090ec15
http://m.itdecent.cn/p/4b6a875694f0
http://jp1017.github.io/2015/12/20/jdk1-8%E6%96%B0%E7%89%B9%E6%80%A7%E4%B9%8Blambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%8F%8A%E5%9C%A8Android-Studio%E4%B8%AD%E7%9A%84%E4%BD%BF%E7%94%A8/

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

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

  • 本文是對 Brian Goetz 的 State of Lambda 一文的翻譯 為什么要翻譯這個系列? andr...
    aaron688閱讀 4,065評論 4 31
  • lambda表達(dá)式(又被成為“閉包”或“匿名方法”)方法引用和構(gòu)造方法引用擴展的目標(biāo)類型和類型推導(dǎo)接口中的默認(rèn)方法...
    183207efd207閱讀 1,553評論 0 5
  • 行為參數(shù)化 為了應(yīng)對多變的需求,難道我們就要因為客戶每提出一個需求,我們就要寫一個方法去實現(xiàn)嗎? 顯然這樣做很冗余...
    uzip柚子皮閱讀 932評論 0 1
  • 注:之前關(guān)于Java8的認(rèn)知一直停留在知道有哪些修改和新的API上,對Lambda的認(rèn)識也是僅僅限于對匿名內(nèi)部類的...
    mualex閱讀 2,944評論 1 4
  • 太陽剛剛升起,一切還都是朦朧一片,萬物都處于這片朦朧之中。不知什么時候一縷晨光照入了這里,萬物慢慢的開始從...
    DHT_ao閱讀 408評論 0 0

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