Java8新特性之Lambda表達式

千山鳥飛絕叫榕,萬徑人蹤滅。 孤舟蓑笠翁寓落,獨釣寒江雪荞下。

寫在前面

還記得上次面試時被問到Java8新特性,我當時居然腦袋一片空白锄弱,然后就GAME OVER了。剛走到大門口才想起來Lambda表達式這個點肖卧,真的是有點失望掸鹅,現(xiàn)在想想主要原因是自己在項目中沒有使用,只是停留在了解層面巍沙,沒有用到項目其實就是就是不會!句携!

就像這Markdown編輯器一個月沒 寫博客,都不會用了削咆。尷尬,一不小心就暴露自己的懶拨齐。

好了廢話少說,開始搞正事厦滤。

Java8新特性中的其他特性歼狼,這里就不說了,主要原因是不能兼容Android7.0以下蹂匹。

Lambda表達式說白了就是一種匿名方法,不需要方法名忍啸,修飾符履植,和返回值類型。

使用方法

首先在moudle的build.gradle文件中添加配置:app/build.gradle添加玫霎。

android {
        ...
        defaultConfig {
        ...
        jackOptions.enabled=true;
    }
    compileOptions{
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    ...
}

就這樣配置就OK了;

接下來我們來看看怎么使用翁脆;

首先拿一個點擊事件來比對一下:
一般寫法

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                
            }
        });

解說:這是一種匿名內(nèi)部類的寫法鼻种,較之外部類的寫法已經(jīng)算是很簡潔了。

Lambda表達式*

        button.setOnClickListener(view ->{
            
        });

解說:不難發(fā)現(xiàn)叉钥,Lambda的這種寫法連匿名內(nèi)部類都不用寫了,更加簡潔了枫疆,直接將參數(shù)暴露在外敷鸦,在方法體中可以直接調(diào)用該參數(shù)寝贡;如果沒有參數(shù)就用()就行钞螟,例如開啟線程的寫法:

            new Thread(() -> {

            });

到這里大家可能就要說了:不就是少了兩行代碼谎碍,有什么了不起,學的時候還不是要從匿名內(nèi)部類寫起蟆淀?

放個大招給你們瞅瞅,在點擊事件中開啟一個線程的:
一般寫法

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                new Thread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }
        });

看起來是不是有點眼花繚亂褒链,很明顯的onClick等方法有點搶鏡疑苔,讓run方法不是那么容易被發(fā)現(xiàn);

Lambda表達式

        button.setOnClickListener( view-> new Thread(() -> {
    
        }));

怎么樣兵迅,是不是被驚艷到了薪贫,服不服?瞧省?Lambda就是這么簡潔,簡潔到?jīng)]朋友鞍匾。

可能有朋友就奇怪怎么寫一起了,不該是兩個分開的Lambda表達式构拳,像這樣嗎梳码,嵌套在一起怎么變樣了?

        button.setOnClickListener(view -> {
            new Thread(() -> {

            });
        });

帶著這個疑問我們從源頭找起掰茶,來看看Lambda表達式到底簡化了什么?
從上面幾個例子我們不難發(fā)現(xiàn)盐碱,Lambda表達式的簡化,其實是簡化了接口的匿名內(nèi)部類的實現(xiàn)和方法

        //一般寫法
        View.OnClickListener listener=new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                
            }
        };
        //Lambda表達式
        View.OnClickListener listener= view -> {

        };

比如在這里Lambda簡化了OnClickListener這個接口的匿名實現(xiàn)和一個必須實現(xiàn)的方法onClick县好,只留下一個參數(shù)View暖混。

那么 到這里,我們大概了解了Lambda表達式的作用拣播,但是心中卻產(chǎn)生了疑問,Lambda表達式的使用范圍廣不廣谍倦?
比如下面提出的一些疑問:

  • Lambda表達式只能簡化接口的匿名實現(xiàn)嗎泪勒?
  • Lambda表達式能簡化多個方法的接口的匿名實現(xiàn)嗎?
  • Lambda表達式能簡化方法里有多個參數(shù)的接口嗎圆存?
  • Lambda表達式能簡化方法帶有返回值的接口嗎?

OK送淆,接下來我們來一一解答:

Lambda表達式只能簡化接口的匿名實現(xiàn)嗎怕轿?

答案是肯定的。

就目前而言Lambda表達式只能簡化接口的匿名內(nèi)部類實現(xiàn)撞羽。
原因大概是:接口是沒有構(gòu)造方法,而抽象類和一般的類是有構(gòu)造方法的谒出;接口里的方法沒有方法體等等邻奠。因為接口的特殊性,Lambda表達式就是只針對接口而已碌宴。

Lambda表達式能簡化多個方法的接口的匿名實現(xiàn)嗎?

答案是不能:這里從Lambda的表達式就可以看出來呜象,已經(jīng)簡化到?jīng)]有沒有一絲多余的代碼,多個方法怎么寫呢恭陡。

結(jié)論

Lambda只能簡化了單一方法接口的實現(xiàn),以及方法的匿名實現(xiàn)著淆;

Lambda表達式能簡化多個參數(shù)的單一方法接口嗎哥捕?

這個答案是肯定的。

前面我在例子中已經(jīng)用到了沒有參數(shù)和一個參數(shù)的接口匿名實現(xiàn)遥赚。

  • 沒有參數(shù)一個空的小括號阐肤;
  • 一個參數(shù)在括號里面添加一個參數(shù),
  • 多個參數(shù)就直接添加就OK了愧薛;
  • 一個參數(shù)時小括號是可以省略的衫画;
  • 另外參數(shù)類型是可以省略的,當然也就可以寫的削罩;
  • 省略括號時是不能寫參數(shù)類型的。

示例如下:

        //沒有參數(shù)
        Runnable runnable=() -> {

        };

        //一個參數(shù)
        View.OnClickListener listener= (View view) -> {

        };
        View.OnClickListener listener= (view) -> {
                  //參數(shù)類型可省略
        };
       View.OnClickListener listener= view -> {
                  //括號可省略进陡,但不能添加參數(shù)
        };

        //兩個參數(shù)
        public interface JackListener{
               void check(String string,String check);
        };
        doWhat("jack666", (string, check) -> {
                //這里的兩個參數(shù)指的是接口里方法的參數(shù)微服,而不是doWhat的參數(shù)哦
        });

Lambda表達式能簡化方法帶有返回值的接口嗎?

答案是肯定的糙麦,其實返回值和簡化前的寫法是一樣丛肮,return一下就可以了。
示例如下:

         //兩個參數(shù)
        public interface JackListener{
            boolean check(String string,String check);
        };
        doWhat("jack666", (string, check) -> {
            boolean result=string.contains(check);
            Toast.makeText(MainActivity.this, ""+result, Toast.LENGTH_SHORT).show();
            return result;
        });

解答完上述幾個問題腾供,我們也就了解了Lambda表達式使用范圍是針對單一方法接口的匿名實現(xiàn)鲜滩,是有很強的針對性节值,并不是哪里都能用的,不過就目前的面向接口編程的大環(huán)境下還是有不小的使用空間嗓蘑。

那現(xiàn)在咱們再來看看最前面的那個問題:兩個Lambda表達式嵌套時匿乃,發(fā)生的化學反應:

        button.setOnClickListener(view -> {
            new Thread(() -> {

            });
        });
        //兩個Lambda表達式嵌套,極簡模式
        button.setOnClickListener( view-> new Thread(() -> {
            //前提是Lambda表達式中的方法體內(nèi)部只有一個單純Lambda表達式
        }));

到這里幢炸,不難發(fā)現(xiàn)外層Lambda表達式的方法體被簡化了,而將內(nèi)部的Lambda表達式銜接在了外層后面佛嬉,就形成了這種極簡的寫法闸天;

那么Lambda表達式能簡化多個Lambda表達式的嵌套嗎,帶著好奇心苞氮,我嘗試了四個Lambda表達式的嵌套:

        //一般寫法
         button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        button.setOnClickListener(new View.OnClickListener()         {
                            @Override
                            public void onClick(View view) {
                                new Thread(new Runnable() {
                                    @Override
                                    public void run() {
                                        
                                    }
                                });
                            }
                        });
                    }
                });
            }
        });
        //四個Lambda表達式嵌套笼吟,CRAZY!!!
        button.setOnClickListener(view -> new Thread(() -> 
              button.setOnClickListener(view1 -> new Thread(() -> {
           
        }))));

當然像這種多層嵌套在開發(fā)環(huán)境中極少能遇到,知道Lambda表達式可以簡化多層嵌套就OK了赞厕。

寫在后面:

從Lambda表達式開始等于開啟了Java的極簡模式,期待下個版本會有更多的簡化毫目,祝福Java在簡化這條路上越走越遠诲侮,讓嘲笑Java臃腫的人去屎

一句話總結(jié)

Lambda簡化了單一方法接口的匿名內(nèi)部類實現(xiàn)沟绪,以及單一方法的匿名實現(xiàn);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恨旱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谆沃,更是在濱河造成了極大的恐慌仪芒,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掂名,死亡現(xiàn)場離奇詭異,居然都是意外死亡锌介,警方通過查閱死者的電腦和手機膀钠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人筑公,你說我怎么就攤上這事》饩龋” “怎么了捣作?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長券躁。 經(jīng)常有香客問我,道長以舒,這世上最難降的妖魔是什么慢哈? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮滥沫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘兰绣。我一直安慰自己,他們只是感情好狭魂,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布雌澄。 她就那樣靜靜地躺著,像睡著了一般镐牺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上募胃,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天畦浓,我揣著相機與錄音,去河邊找鬼讶请。 笑死,一個胖子當著我的面吹牛论巍,可吹牛的內(nèi)容都是我干的风响。 我是一名探鬼主播嘉汰,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鞋怀,長吁一口氣:“原來是場噩夢啊……” “哼荧降!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起朵诫,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后废累,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡日缨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年匣距,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毅待。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡归榕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出外里,到底是詐尸還是另有隱情,我是刑警寧澤盅蝗,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布姆蘸,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏题山。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一玖姑、第九天 我趴在偏房一處隱蔽的房頂上張望慨菱。 院中可真熱鬧焰络,春花似錦符喝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽描馅。三九已至,卻和暖如春恋日,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背岂膳。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工刁绒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人傻盟。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓嫂丙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親跟啤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

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

  • 一竿奏、什么是lambda表達式腥放? “Lambda 表達式”(lambda expression)是一個匿名函數(shù),La...
    OchardBird閱讀 735評論 1 3
  • 簡介 概念 Lambda 表達式可以理解為簡潔地表示可傳遞的匿名函數(shù)的一種方式:它沒有名稱候址,但它有參數(shù)列表、函數(shù)主...
    劉滌生閱讀 3,201評論 5 18
  • lambda表達式(又被成為“閉包”或“匿名方法”)方法引用和構(gòu)造方法引用擴展的目標類型和類型推導接口中的默認方法...
    183207efd207閱讀 1,481評論 0 5
  • Java8 新特性(一) - Lambda 表達式 近些日子一直在使用和研究 golang,很長時間沒有關(guān)心 ja...
    不智魚閱讀 1,325評論 1 3
  • 今天我們又去了揚城湖荠雕,中國歷史文化名城揚州,地處江蘇中部舞虱,長江下游北岸,江淮平原南端矾兜。揚州城區(qū)至今已有近...
    寧莉閱讀 420評論 1 0