我也說說java8的新特性

本文地址:http://www.reibang.com/p/dd24738d2b11

寫在前面:

Java8已經(jīng)發(fā)布很久了杠人,但是安卓官方對(duì)它的支持一直不是很完整砰粹,直到最近發(fā)布的Android Studio 3預(yù)覽版才支持了函數(shù)式接口,集合的聚合操作等咙好,所以現(xiàn)在有必要真正地來去學(xué)習(xí)它了篡腌。
本文主要針對(duì)Android Studio(3.0 canary1)對(duì)java api支持的部分做說明,當(dāng)然勾效,這部分的特性也完全是java8的一些特性嘹悼,是其一個(gè)子集而沒有其它差異之處叛甫。
本來這篇東西涉及到了java8的好幾個(gè)特性,包括函數(shù)式接口杨伙,一些標(biāo)準(zhǔn)的函數(shù)式接口其监,集合的聚合操作和lambda表達(dá)式,但是一通了解準(zhǔn)備下來限匣,發(fā)現(xiàn)它們都是圍繞著函數(shù)式接口這一個(gè)東西在呈現(xiàn)的抖苦,并且內(nèi)容并不復(fù)雜,所以我打算用這一篇把這幾個(gè)特性都講了吧膛腐。當(dāng)然睛约,我這里只是挑最重要最核心最能讓大家明白的幾點(diǎn)來講,需要更詳細(xì)了解更多用法和細(xì)節(jié)的可以參看文末的官方文檔地址哲身。

既然說是圍繞函數(shù)式接口來呈現(xiàn)的辩涝,那我們就先從函數(shù)式接口開始說起吧。

函數(shù)式接口

定義:

只有一個(gè)抽象方法的接口

( 當(dāng)然勘天,這是我的白話定義怔揩,刪繁就簡(jiǎn)我們就不啰嗦它的那些default方法和靜態(tài)方法了。這兩個(gè)特性完全只是對(duì)接口的一些能力擴(kuò)展脯丝,不必大驚小怪商膊,所以也是為什么我覺得不需要另外一篇文章介紹這些特性。)

這個(gè)定義就是專門為了lambda表達(dá)式的應(yīng)用而設(shè)計(jì)的宠进。只要理解到這里就可以了晕拆,事實(shí)也就這些吧。它并沒有新的東西材蹬。倒是api里創(chuàng)建了一堆標(biāo)準(zhǔn)的函數(shù)式接口給各位使用实幕,就是下面講的這個(gè):

標(biāo)準(zhǔn)函數(shù)式接口

java8硬是要提供這么一個(gè)“工具類”(嗯,因?yàn)樗旁诹薺ava.util.function包下堤器,我們確實(shí)完全可以理解成是一個(gè)工具)昆庇,我想也是極力引導(dǎo)大家運(yùn)用依賴倒置的原則吧,啥擴(kuò)展代碼都不要寫進(jìn)原有方法里面闸溃,只使用這些標(biāo)準(zhǔn)接口對(duì)接相應(yīng)的輸入輸出類型整吆,原有方法就只調(diào)用這些接口……但這是不是想多了啊辉川?我們需要擴(kuò)展的時(shí)候表蝙,自然會(huì)自己定義一個(gè)合理的(起碼名字更好理解的)接口來解耦代碼,真需要你提供這么一堆乓旗?但既然提供了府蛇,我們也只好試著將就著勉強(qiáng)著用用先吧,起碼在輸入輸出類型一致時(shí)寸齐,我們不需要去定義多個(gè)功能相同的接口吧(可能設(shè)計(jì)者就只是這么想呢欲诺。。渺鹦。確實(shí)扰法,就是為了省點(diǎn)代碼?作為jdk毅厚,這是不是管得太寬想得太多了塞颁?這是不是過度設(shè)計(jì)了?為了省點(diǎn)代碼吸耿,讓api變累贅祠锣?成功與否,看大家接受程度如何吧咽安!記憶這些接口是一回事伴网,我個(gè)人是推崇更自由地編寫代碼的,包括思想上的自由妆棒,不是由你來給我設(shè)計(jì)接口澡腾,當(dāng)然如果自己不會(huì)設(shè)計(jì)接口,那是水平問題糕珊,這門檻也不高动分,不應(yīng)該由jdk來做約束,限制了會(huì)設(shè)計(jì)接口的人的自由红选±焦——這有點(diǎn)像搖號(hào),看似解決問題喇肋,但卻傷害著所有人的根本利益坟乾。當(dāng)然,你會(huì)說你也還可以自己定義接口啊苟蹈。但這不一樣糊渊,你既然提供了一個(gè)這樣的東西,你對(duì)整個(gè)環(huán)境的影響是在的慧脱,我定義接口時(shí)就不得不考慮那些使用這些標(biāo)準(zhǔn)接口的人渺绒,甚至說不定有些團(tuán)隊(duì)還會(huì)因此而將標(biāo)準(zhǔn)接口列入編碼規(guī)范,這些影響都是客觀的菱鸥,事物都是相互聯(lián)系相互影響的宗兼。扯遠(yuǎn)了,不過也可以幫助大家理解這個(gè)函數(shù)式接口吧)

java8內(nèi)置的幾個(gè)標(biāo)準(zhǔn)函數(shù)式接口:

Predicate

boolean test(T)
表示判斷氮采。輸入一個(gè)對(duì)象殷绍,返回布爾值

Consumer

void accept(T)
消費(fèi)一個(gè)操作。輸入一個(gè)對(duì)象鹊漠,處理(消費(fèi))完后不返回值

Supplier

T get()
直接返回一個(gè)對(duì)象

Function

R apply(T)
就是函數(shù)映射的意思主到,一個(gè)輸入茶行,一個(gè)相應(yīng)的輸出

主要是以上4種接口了,另外還有很多都是在這幾種的基礎(chǔ)之上的擴(kuò)展登钥,比如加前綴Bi的表示輸入兩個(gè)參數(shù)畔师,加了類型Int的表示返回的類型用int類型等等。

又一個(gè)題外話——
這樣只需要在使用的時(shí)候?qū)憣?shí)現(xiàn)牧牢, 類不需要再變看锉。但省去了很多信息,是否真的有必要這樣塔鳍?更何況也不是所有函數(shù)都需要擴(kuò)展伯铣,這樣是不是太過了?原有的類是不變了轮纫,但擴(kuò)展時(shí)時(shí)都要變呢腔寡。

Lambda表達(dá)式

作用

在方法中只有一條語句時(shí),省略更多代碼掌唾。

語法

1.包括一個(gè)箭頭->
2.箭頭左邊是參數(shù)蹬蚁,可以各種省略類型和括號(hào)
3.箭頭右邊是函數(shù)體,可以各種省略花括號(hào)和關(guān)鍵字return

使用場(chǎng)景

實(shí)際上郑兴,lambda表達(dá)式只能在函數(shù)式接口上使用犀斋。 就是為了在只有一個(gè)方法時(shí)省點(diǎn)代碼。

另外情连,因?yàn)樗雌饋砗芟褚粋€(gè)函數(shù)叽粹,所以你可以當(dāng)它是一個(gè)匿名方法----沒有名字的方法 (來自于官方網(wǎng)址的說明哦)

下面,舉例說明一下lambda表達(dá)式在各種具體場(chǎng)景中的運(yùn)用吧:

  • 函數(shù)式接口中:
setOnClickListener(view->view.setAlpha(255));

相當(dāng)于

setOnClickListener(new OnClickListener(){
    public void onClick(View view){
        view.setAlpha(255);
    }
})
  • 標(biāo)準(zhǔn)函數(shù)式接口也一樣却舀,只不過接口是由jdk提供的(android里由安卓sdk提供)虫几,具體可參看文末提供的官網(wǎng)鏈接里的例子。由于代碼量較多就不貼了挽拔。

  • 還有個(gè)泛型的應(yīng)用:

public static <X, Y> void processElements(
            Iterable<X> source,
            Predicate<X> tester,
            Function <X, Y> mapper,
            Consumer<Y> block) {
        for (X p : source) {
            if (tester.test(p)) {
                Y data = mapper.apply(p);
                block.accept(data);
            }
        }
    }
    
調(diào)用時(shí):
processElements(
        new ArrayList<Person>(3),
        p -> p.getAge() <= 25,
        p -> p.getAge(),
        age -> System.out.println(age)
);

這個(gè)泛型要注意的是辆脸,它的類型由最先使用到它的那個(gè)地方來確定,比如Y類型螃诅,就是由最先使用到它的mapper返回getAge時(shí)來確定是int類型的啡氢,在block輸入Y時(shí)就是個(gè)int類型,也就是在打印時(shí)age是個(gè)int類型术裸。

  • 另外倘是,順帶講一下集合的聚合操作

java8對(duì)響應(yīng)式編程的這一點(diǎn)支持是最值得稱贊的,這一塊需要另外講一篇袭艺。我們還是先講回lambda表達(dá)式搀崭。
其實(shí)這個(gè)跟lambda沒有什么必然聯(lián)系,聚合操作是java8為集合提供的一個(gè)方便的流式寫法猾编。只不過由于其中的參數(shù)都剛好是函數(shù)式接口瘤睹,所以也可以用lambda來表示而已升敲。它也可以不用lambda來表示,絲毫不影響這個(gè)聚合操作的優(yōu)點(diǎn)發(fā)光發(fā)熱轰传。

new ArrayList<Person>()
      .stream()
      .filter(p -> p.getAge() >= 18 && p.getAge() <= 25)
      .map(p -> p.getAge())//相當(dāng)于Function接口冻晤,map在這里是(函數(shù))映射的意思
      .forEach(age -> System.out.println(age));

Lambda表達(dá)式變量的作用域

這一點(diǎn)的最后,還要提一下變量在lambda表達(dá)式中的作用域(這才是最實(shí)在的語法糖)

1.lambda函數(shù)體里可直接訪問方法傳遞過來的參數(shù)绸吸,但此時(shí)相當(dāng)于認(rèn)為該參數(shù)是final型的,不允許再次賦值
2.lambda函數(shù)體里的this指的是函數(shù)外面最近一層類的實(shí)例设江,不是指函數(shù)所代表的接口實(shí)例

方法引用

方法引用是在lambda表達(dá)式中特定情形下锦茁,使用的特定表示語法。
具體限定為:當(dāng)傳過來的參數(shù)列表跟要調(diào)用的方法的參數(shù)能對(duì)應(yīng)上叉存,并且lambda函數(shù)體內(nèi)只有一個(gè)方法調(diào)用語句時(shí)码俩,如果符合以下四種情形之一,可以使用方法引用的語法(使用雙冒號(hào)::)來表示歼捏。

1.靜態(tài)方法

ContainingClass::staticMethodName

2.實(shí)例方法

containingObject::instanceMethodName

3.特定類型的實(shí)例方法

ContainingType::methodName

4.構(gòu)造器的使用

ClassName::new

比如:
Arrays.sort(rosterAsArray, Person::compareByAge);
相當(dāng)于:
Arrays.sort(rosterAsArray,
    (a, b) -> Person.compareByAge(a, b)
);
這是靜態(tài)方法類型的使用稿存,其它類型可參見官網(wǎng)相關(guān)章節(jié)。

需要注意的是瞳秽,它只能在代替lambda表達(dá)式的時(shí)候使用瓣履。也就限定了只能在函數(shù)式接口上使用了,不能單獨(dú)當(dāng)作一句普通表達(dá)式來用的练俐。比如袖迎,單獨(dú)寫這么一句:
Person::compareByAge;//這是不行的腺晾,哪怕那個(gè)方法是個(gè)不需要參數(shù)的也不行燕锥。

官方文檔地址:
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

相關(guān)文章:
http://blog.csdn.net/qq_28899635/article/details/53691986

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市悯蝉,隨后出現(xiàn)的幾起案子归形,更是在濱河造成了極大的恐慌,老刑警劉巖鼻由,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暇榴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蕉世,警方通過查閱死者的電腦和手機(jī)跺撼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讨彼,“玉大人歉井,你說我怎么就攤上這事哈误×ㄖ粒” “怎么了躏嚎?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)菩貌。 經(jīng)常有香客問我卢佣,道長(zhǎng),這世上最難降的妖魔是什么箭阶? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任虚茶,我火速辦了婚禮,結(jié)果婚禮上仇参,老公的妹妹穿的比我還像新娘嘹叫。我一直安慰自己,他們只是感情好诈乒,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布罩扇。 她就那樣靜靜地躺著,像睡著了一般怕磨。 火紅的嫁衣襯著肌膚如雪喂饥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天肠鲫,我揣著相機(jī)與錄音员帮,去河邊找鬼。 笑死导饲,一個(gè)胖子當(dāng)著我的面吹牛集侯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播帜消,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼棠枉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了泡挺?” 一聲冷哼從身側(cè)響起辈讶,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娄猫,沒想到半個(gè)月后贱除,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡媳溺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年月幌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悬蔽。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扯躺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情录语,我是刑警寧澤倍啥,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站澎埠,受9級(jí)特大地震影響虽缕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蒲稳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一氮趋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧江耀,春花似錦剩胁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倍踪。三九已至系宫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間建车,已是汗流浹背扩借。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缤至,地道東北人潮罪。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像领斥,于是被迫代替她去往敵國(guó)和親嫉到。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

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

  • Java8 in action 沒有共享的可變數(shù)據(jù)月洛,將方法和函數(shù)即代碼傳遞給其他方法的能力就是我們平常所說的函數(shù)式...
    鐵牛很鐵閱讀 1,220評(píng)論 1 2
  • 簡(jiǎn)介 概念 Lambda 表達(dá)式可以理解為簡(jiǎn)潔地表示可傳遞的匿名函數(shù)的一種方式:它沒有名稱何恶,但它有參數(shù)列表、函數(shù)主...
    劉滌生閱讀 3,194評(píng)論 5 18
  • 在C++11中嚼黔,我們還是會(huì)看到一些新元素细层。這些新鮮出爐的元素可能會(huì)帶來一些習(xí)慣上的改變,不過權(quán)衡之下唬涧,可能這樣的改...
    認(rèn)真學(xué)計(jì)算機(jī)閱讀 5,469評(píng)論 1 27
  • lambda表達(dá)式(又被成為“閉包”或“匿名方法”)方法引用和構(gòu)造方法引用擴(kuò)展的目標(biāo)類型和類型推導(dǎo)接口中的默認(rèn)方法...
    183207efd207閱讀 1,473評(píng)論 0 5
  • 注:之前關(guān)于Java8的認(rèn)知一直停留在知道有哪些修改和新的API上,對(duì)Lambda的認(rèn)識(shí)也是僅僅限于對(duì)匿名內(nèi)部類的...
    mualex閱讀 2,819評(píng)論 1 4