關(guān)于Lambda表達式的整理

前段時間的面試基本結(jié)束了,最后也有了不錯的結(jié)果骚亿,之后一段時間到入職打算好好整理一些東西诵闭。
想到馬上Java9也要出來了,Android也馬上支持Java8咪惠,自己都沒有好好整理過java8比較重要的知識點击吱,可以說8很多改動都是為了Lambda服務(wù)的,所以整理一下Lambda的內(nèi)容遥昧。

關(guān)于閉包

首先閉包是指覆醇,將當前作用域中的變量通過值或者引用的方式封裝到lambda表達式中,成為表達式的一部分炭臭,它使你的lambda表達式從一個普通的函數(shù)變成帶隱藏參數(shù)的函數(shù)永脓,當然閉包也可以不通過lambda實現(xiàn)

簡單理解為閉包就是定義在函數(shù)內(nèi)部的函數(shù)

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

  • Lambda 表達式與匿名類的主要不同在于兩者的編譯方法
  • 對于匿名類,關(guān)鍵詞 this 解讀為匿名類鞋仍,而對于 Lambda 表達式常摧,關(guān)鍵詞 this 解讀為寫就 Lambda 的外部類

什么時候用

任何可以接受一個函數(shù)式接口的地方都可以用lambda表達式
lambda作用在于

  • 邏輯更緊湊
  • 引入閉包,更簡潔的實現(xiàn)閉包
  • 允許函數(shù)方法作為對象傳遞

函數(shù)式接口

定義

所謂的函數(shù)式接口凿试,也叫SAM接口(Single Abstract Method interfaces)排宰,當然首先是一個接口似芝,然后就是在這個接口里面只能有一個抽象方法

  • 函數(shù)式接口里允許定義默認方法
  • 函數(shù)式接口里允許定義靜態(tài)方法
  • 函數(shù)式接口里允許定義java.lang.Object里的public方法
    //以下都是不會報錯的
    @FunctionalInterface
    interface GreetingService{
        void sayMessage(String message);

        default void doSomeMoreWork1()
        {
            // Method body
        }
        static void printHello(){
            System.out.println("Hello");
        }
        @Override
        boolean equals(Object obj);
    }

@FunctionalInterface注解

加不加@FunctionalInterface對于接口是不是函數(shù)式接口沒有影響,只是提醒編譯器去檢查該接口是否僅包含一個抽象方法板甘,用于編譯級錯誤檢查

新增java.util.function

  • Predicate:用于判斷一個對象是否滿足某種條件党瓮,只有一個test抽象函數(shù),接受一個泛型T對象返回boolean
  • Consumer:用于對對象進行消費操作盐类,只有一個accept抽象函數(shù)寞奸,接受一個泛型對象無返回
  • Function:用于對象的轉(zhuǎn)換,只有一個apply抽象函數(shù)在跳,接受一個泛型T枪萄,返回一個泛型R
  • Supplier:用于創(chuàng)建對象
  • 還有一些衍生的可以自己看包下源碼

使用

使用相信大家都會一些,我就不列舉猫妙,網(wǎng)上大把的文章瓷翻,下面兩篇總結(jié)不錯

深入理解Java 8 Lambda(語言篇——lambda,方法引用割坠,目標類型和默認方法)

10個實例表達式

原理

Java 編譯器編譯 Lambda 表達式并將他們轉(zhuǎn)化為類里面的私有靜態(tài)函數(shù)

  • 它使用 Java 7 中新加的 invokedynamic齐帚,運行時調(diào)用LambdaMetafactory.metafactory動態(tài)的生成內(nèi)部類,實現(xiàn)了接口
  • 生成一個類私有靜態(tài)函數(shù)彼哼,在生成的實現(xiàn)類中調(diào)用

關(guān)于 Java 如何將 Lambda 表達式編譯為字節(jié)碼

國外的一篇寫的不錯

通俗易懂的解釋

interface Print<T> {
    public void print(T x);
}
public class Lambda {   
    public static void PrintString(String s, Print<String> print) {
        print.print(s);
    }
    public static void main(String[] args) {
        PrintString("test", (x) -> System.out.println(x));
    }
}

通過編譯最終等價于

interface Print<T> {
    public void print(T x);
}
public class Lambda {   
    public static void PrintString(String s, Print<String> print) {
        print.print(s);
    }
    private static void lambda$0(String x) {
        System.out.println(x);
    }
    final class $Lambda$1 implements Print{
        @Override
        public void print(Object x) {
            lambda$0((String)x);
        }
    }
    public static void main(String[] args) {
        PrintString("test", new Lambda().new $Lambda$1());
    }
}

關(guān)于性能

Oracle寫的lambda表現(xiàn)文檔

16頁講到最差(capture)也和inner class一樣对妄, non-capture好的情況是inner class的5倍

image1
image1

但是在使用Stream的時候并不是所有情況都比普通迭代快的

下面這篇文章比較了各種情況下imperative code與functional code的性能表現(xiàn)

The effects of programming with Java 8 Streams on algorithm performance

關(guān)于Streams

Lambda最佳結(jié)合應(yīng)該就是Stream了,函數(shù)式編程與簡潔的結(jié)合
Java 8的Stream內(nèi)置了許多類似于數(shù)據(jù)庫的操作filter敢朱、sort剪菱、map、reduce等
用法就不貼了拴签,大把文章
官方的在這里

Stream優(yōu)點:

  • 以數(shù)據(jù)庫操作數(shù)據(jù)的方式孝常,專注于如何做這個某個步驟,表達式的方式

  • 高并發(fā)(看到map篓吁、reduce就應(yīng)該能想到了)

剛開始看Stream感覺和RxJava非常像茫因,但是仔細思索后有發(fā)現(xiàn)其實是兩個不同的東西,只是長得像而已杖剪。
下面這個最高票回答總結(jié)的非常好,總體來說

  • stream是單次使用驰贷,是基于被動PULL
  • rx是基于觀察者模式盛嘿,可多次訂閱,是基于主動PUSH

Stream與Rxjava的不同

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末括袒,一起剝皮案震驚了整個濱河市次兆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锹锰,老刑警劉巖芥炭,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漓库,死亡現(xiàn)場離奇詭異,居然都是意外死亡园蝠,警方通過查閱死者的電腦和手機渺蒿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彪薛,“玉大人茂装,你說我怎么就攤上這事∩蒲樱” “怎么了少态?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長易遣。 經(jīng)常有香客問我彼妻,道長,這世上最難降的妖魔是什么豆茫? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任侨歉,我火速辦了婚禮,結(jié)果婚禮上澜薄,老公的妹妹穿的比我還像新娘为肮。我一直安慰自己,他們只是感情好肤京,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布颊艳。 她就那樣靜靜地躺著,像睡著了一般忘分。 火紅的嫁衣襯著肌膚如雪棋枕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天妒峦,我揣著相機與錄音重斑,去河邊找鬼。 笑死肯骇,一個胖子當著我的面吹牛窥浪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笛丙,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼漾脂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胚鸯?” 一聲冷哼從身側(cè)響起骨稿,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后坦冠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體形耗,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年辙浑,在試婚紗的時候發(fā)現(xiàn)自己被綠了激涤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡例衍,死狀恐怖昔期,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情佛玄,我是刑警寧澤硼一,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站梦抢,受9級特大地震影響般贼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奥吩,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一哼蛆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧霞赫,春花似錦腮介、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至旅东,卻和暖如春灭抑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抵代。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工腾节, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荤牍。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓案腺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親康吵。 傳聞我的和親對象是個殘疾皇子救湖,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

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

  • 本文是對 Brian Goetz 的 State of Lambda 一文的翻譯 為什么要翻譯這個系列耍铜? andr...
    aaron688閱讀 3,892評論 4 31
  • 摘要:此篇文章主要介紹 Java8 Lambda 表達式產(chǎn)生的背景和用法邑闺,以及 Lambda 表達式與匿名類的不同...
    OneAPM閱讀 2,079評論 0 26
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)棕兼,斷路器陡舅,智...
    卡卡羅2017閱讀 134,704評論 18 139
  • lambda表達式(又被成為“閉包”或“匿名方法”)方法引用和構(gòu)造方法引用擴展的目標類型和類型推導(dǎo)接口中的默認方法...
    183207efd207閱讀 1,486評論 0 5
  • 《斷劍》 文/劉漢皇 劍死了,在絕望中死去在轟鳴的車間死去在高大的煉鋼爐融化死去的還有他的魂伴挚,他的夢 他飲過匈奴的...
    劉漢皇閱讀 515評論 15 8