lambda表達(dá)式

最近在學(xué)習(xí)kotlin的時(shí)候舟陆,其中有一章節(jié)專門講kotlin的高階函數(shù)和 lambda 表達(dá)式浪感,兩者配合使用可以讓代碼極致的簡潔,今天 來了解一下lambda 表達(dá)式相關(guān)的知識(shí)。

在很多高級(jí)語言中都是有lambda 表達(dá)式的擎值,比如:Python、Javascript逐抑、C#鸠儿、Objective-C......

Lambda表達(dá)式在Java 8中被引入,被稱為Java 8的最大特征厕氨。Lambda表達(dá)式有助于函數(shù)式編程进每,并且簡化了開發(fā)工作。(關(guān)于函數(shù)式編程可以看一下阮一峰的函數(shù)式編程初探)命斧。

lambda表達(dá)式簡介

Lambda 允許把函數(shù)作為一個(gè)方法的參數(shù)(函數(shù)作為參數(shù)傳遞進(jìn)方法中)田晚,使用 Lambda 表達(dá)式可以使代碼變的更加簡潔緊湊。但是Java中的lambda無法單獨(dú)出現(xiàn)国葬,它需要一個(gè)函數(shù)式接口來盛放贤徒,lambda表達(dá)式方法體其實(shí)就是函數(shù)接口的實(shí)現(xiàn)芹壕。

函數(shù)式接口functional interface

我們把只擁有一個(gè)方法的接口稱為 函數(shù)式接口。(之前它們被稱為 SAM類型接奈,即 單抽象方法類型(Single Abstract Method))踢涌。

例如:android中android.view.View.OnClickListener其實(shí)就是一個(gè)函數(shù)式接口

/**
 * Interface definition for a callback to be invoked when a view is clicked.
 */
public interface OnClickListener {
    /**
     * Called when a view has been clicked.
     *
     * @param v The view that was clicked.
     */
    void onClick(View v);
}

lambda表達(dá)式實(shí)際場景

例如:在android中我給一個(gè)ImageView設(shè)置了一個(gè)點(diǎn)擊事件序宦,代碼如下:

mIvLogo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println("Hello");
            }
        });

那么我們用lambda表達(dá)式的代碼如下:

mIvLogo.setOnClickListener(v -> System.out.println("Hello"));

匿名類型最大的問題就在于其冗余的語法睁壁。有人戲稱匿名類型導(dǎo)致了“高度問題”(height problem):在 OnClickListener這個(gè)例子里的五行代碼中僅有一行在做實(shí)際工作,但是我們不得不寫5行代碼互捌。

lambda語法

lambda表達(dá)式由三部分組成:

Argument List Arrow Token Body
(int x, int y) -> x + y

lambda 表達(dá)式的語法格式如下:

(parameters) -> expression 或 (parameters) ->{ statements; }

以下是lambda表達(dá)式的重要特征:

  • 可選類型聲明:無需聲明參數(shù)的類型堡僻。編譯器可以跟參數(shù)的值推斷出參數(shù)的類型。
  • 可選的參數(shù)圓括號(hào):一個(gè)參數(shù)無需定義圓括號(hào)疫剃,但多個(gè)參數(shù)必須定義圓括號(hào)钉疫。
  • 可選的大括號(hào):如果Body只包含一個(gè)語句,可以不使用大括號(hào)巢价。
  • 可選的返回關(guān)鍵字:如果Body只有一個(gè)表達(dá)式返回值則編譯器會(huì)自動(dòng)返回值(無需寫return關(guān)鍵字)牲阁,需要花括號(hào)表示表達(dá)式返回值。

lambda語法范例

public class Java8Tester {
    public static void main(String[] args) {
        Java8Tester tester = new Java8Tester();

        //含類型聲明
        MathOperation addition = (int a, int b) -> a + b;

        //無類型聲明
        MathOperation subtraction = (a, b) -> a - b;

        //帶有大括號(hào)的返回語句
        MathOperation multiplication = (int a, int b) -> { return a * b; };

        //不帶大括號(hào)和return語句
        MathOperation division = (int a, int b) -> a / b;

        System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
        System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
        System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
        System.out.println("10 / 5 = " + tester.operate(10, 5, division));

        //參數(shù)不帶圓括號(hào)
        GreetingService greetService1 = message ->
                System.out.println("Hello " + message);

        //參數(shù)帶圓括號(hào)
        GreetingService greetService2 = (message) ->
                System.out.println("Hello " + message);

        greetService1.sayMessage("Mahesh");
        greetService2.sayMessage("Suresh");
    }

    interface MathOperation {
        int operation(int a, int b);
    }

    interface GreetingService {
        void sayMessage(String message);
    }

    private int operate(int a, int b, MathOperation mathOperation){
        return mathOperation.operation(a, b);
    }
}

lambda表達(dá)式在android中使用

android studio配置

下面介紹一下官方和三方的支持:

android官方支持

在Android Studio 3.0之后

Android Studio 3.0預(yù)覽1及更高版本支持對(duì)Java 8語言進(jìn)行了支持壤躲,要想使用java8的功能城菊,請(qǐng)確保你的Android Plugin for Gradle版本為3.0.0-alpha1(或更高)。然后在你模塊級(jí)別的 build.gradle 文件中添加以下內(nèi)容:

android {
  ...
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}
在Android Studio 3.0之前

要為您的項(xiàng)目啟用 Java 8 語言功能和 Jack碉克,請(qǐng)?jiān)谥鱩odel的 build.gradle 文件中輸入以下內(nèi)容:

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

注意:

  • Jack 僅在 Android Studio 2.1 和更高版本上才受支持凌唬。
  • 使用Jack的話將會(huì)導(dǎo)致Instant Run不可用
三方支持庫

retrolambda插件

下面介紹一下如何使用:

step1 在project級(jí)別的 build.gradle文件中添加如下代碼:

buildscript {
   repositories {
     // Required because retrolambda is on maven central
      mavenCentral()
   }

   dependencies {
      classpath 'me.tatarka:gradle-retrolambda:3.6.1'
   }
}

step2 在主model的 build.gradle文件中添加如下代碼:

apply plugin: 'me.tatarka.retrolambda'
android {
  ...
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

在android中的使用場景

new Handler().postDelayed(() -> {
    Toast.makeText(this, "2s后執(zhí)行", Toast.LENGTH_SHORT).show();
}, 2000);
mIvLogo.setOnLongClickListener(v -> {
    System.out.println("onLongClick");
    return false;
});
mIvLogo.setOnTouchListener((v, event) -> {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
        System.out.println("ACTION_DOWN");
    }
    return false;
});

注意:必須是函數(shù)式接口才可以使用lambda表達(dá)式。

android的場景其實(shí)很多的漏麦,在以后的使用過程中客税,我會(huì)把比較典型的陸續(xù)補(bǔ)充上來。

參考文檔

oracle官網(wǎng)文檔 Lambda Quick Start

oracle官網(wǎng)文檔 Lambda Expressions

android官方文檔 使用 Java 8 語言功能

android studio 3.0預(yù)覽版功能介紹 Use Java 8 language features

原文地址:https://zhouyang-cn.github.io/2017/06/10/lambda-expressions/

轉(zhuǎn)載請(qǐng)注明原文地址撕贞,謝謝更耻!。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捏膨,一起剝皮案震驚了整個(gè)濱河市秧均,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌号涯,老刑警劉巖目胡,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異链快,居然都是意外死亡誉己,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門久又,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巫延,“玉大人效五,你說我怎么就攤上這事地消÷澹” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵脉执,是天一觀的道長疼阔。 經(jīng)常有香客問我,道長半夷,這世上最難降的妖魔是什么婆廊? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任受葛,我火速辦了婚禮霍骄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘屏积。我一直安慰自己湘换,他們只是感情好宾舅,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著彩倚,像睡著了一般筹我。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上帆离,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天蔬蕊,我揣著相機(jī)與錄音,去河邊找鬼哥谷。 笑死岸夯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的们妥。 我是一名探鬼主播囱修,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼王悍!你這毒婦竟也來了破镰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤压储,失蹤者是張志新(化名)和其女友劉穎鲜漩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體集惋,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡孕似,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了刮刑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喉祭。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡养渴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出泛烙,到底是詐尸還是另有隱情理卑,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布蔽氨,位于F島的核電站藐唠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鹉究。R本人自食惡果不足惜宇立,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望自赔。 院中可真熱鬧妈嘹,春花似錦、人聲如沸绍妨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痘绎。三九已至津函,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孤页,已是汗流浹背尔苦。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留行施,地道東北人允坚。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像蛾号,于是被迫代替她去往敵國和親稠项。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,504評(píng)論 25 707
  • 寫在開頭 Lambda ,希臘字母 “λ” 的英文名稱鲜结。沒錯(cuò)展运,就是你高中數(shù)學(xué)老師口中的那個(gè)“蘭布達(dá)”。在編程世界中...
    丨ZhZh丨閱讀 969評(píng)論 0 2
  • 簡介 概念 Lambda 表達(dá)式可以理解為簡潔地表示可傳遞的匿名函數(shù)的一種方式:它沒有名稱精刷,但它有參數(shù)列表拗胜、函數(shù)主...
    劉滌生閱讀 3,193評(píng)論 5 18
  • 聲明:本文翻譯自The Java? Tutorials(官方文檔) 簡述 匿名類有一個(gè)問題,如果匿名類的實(shí)現(xiàn)非常簡...
    猴子小皮球閱讀 4,631評(píng)論 0 9
  • "女漢子"的俠骨柔腸 “女漢子”與“女神”怒允,你更愛哪一個(gè)埂软?我想多數(shù)男士會(huì)毫不猶豫的選擇后者...
    徐囡囡閱讀 465評(píng)論 0 21