Java8 函數(shù)式編程

1. 概述

1.1 函數(shù)式編程簡(jiǎn)介

常見(jiàn)的編程范式:

命令式編程(Imperative Programming),邏輯式編程(Logic Programming),函數(shù)式編程(Functional Programming)。

函數(shù)式編程作為一種編程范式,在科學(xué)領(lǐng)域,是一種編寫(xiě)計(jì)算機(jī)程序數(shù)據(jù)結(jié)構(gòu)和元素的方式,它把計(jì)算過(guò)程當(dāng)做是數(shù)學(xué)函數(shù)的求值庆锦,而避免更改狀態(tài)和可變數(shù)據(jù)。

什么是函數(shù)式編程轧葛?簡(jiǎn)單的回答:一切都是數(shù)學(xué)函數(shù)搂抒。函數(shù)式編程語(yǔ)言里也可以有對(duì)象,但通常這些對(duì)象都是恒定不變的 ——

要么是函數(shù)參數(shù)尿扯,要什么是函數(shù)返回值求晶。函數(shù)式編程語(yǔ)言里沒(méi)有 for/next

循環(huán),因?yàn)檫@些邏輯意味著有狀態(tài)的改變衷笋。相替代的是,這種循環(huán)邏輯在函數(shù)式編程語(yǔ)言里是通過(guò)遞歸辟宗、把函數(shù)當(dāng)成參數(shù)傳遞的方式實(shí)現(xiàn)的。

舉個(gè)例子:

a = a +1

這段代碼在普通成員看來(lái)并沒(méi)有什么問(wèn)題泊脐,但在數(shù)學(xué)家看來(lái)確實(shí)不成立的空幻,因?yàn)樗馕吨兞恐档酶淖儭?/p>

1.2 Lambda 表達(dá)式簡(jiǎn)介

2.1 Lambda 表達(dá)式的形式

Java 中 Lambda 表達(dá)式一共有五種基本形式容客,具體如下:

?

Runnable noArguments = () -> System.out.println("Hello World");

?

ActionListener oneArgument = event -> System.out.println("button clicked");

?

Runnable multiStatement = () -> {? ? System.out.print("Hello");? ? System.out.println(" World");};

?

BinaryOperator<Long> add = (x, y) -> x + y;

?

BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y;

?中所示的 Lambda 表達(dá)式不包含參數(shù),使用空括號(hào) () 表示沒(méi)有參數(shù)。該 Lambda 表達(dá)式 實(shí)現(xiàn)了 Runnable

接口,該接口也只有一個(gè) run 方法,沒(méi)有參數(shù),且返回類(lèi)型為 void缩挑。?中所示的 Lambda

表達(dá)式包含且只包含一個(gè)參數(shù),可省略參數(shù)的括號(hào),這和例 2-2 中的 形式一樣。Lambda

表達(dá)式的主體不僅可以是一個(gè)表達(dá)式,而且也可以是一段代碼塊,使用大括號(hào)

({})將代碼塊括起來(lái),如?所示供置。該代碼塊和普通方法遵循的規(guī)則別無(wú)二致,可以用返 回或拋出異常來(lái)退出谨湘。只有一行代碼的 Lambda

表達(dá)式也可使用大括號(hào),用以明確 Lambda表達(dá)式從何處開(kāi)始悲关、到哪里結(jié)束。Lambda

表達(dá)式也可以表示包含多個(gè)參數(shù)的方法,如?所示寓辱。這時(shí)就有必要思考怎樣去閱 讀該 Lambda

表達(dá)式。這行代碼并不是將兩個(gè)數(shù)字相加,而是創(chuàng)建了一個(gè)函數(shù),用來(lái)計(jì)算 兩個(gè)數(shù)字相加的結(jié)果妇汗。變量 add 的類(lèi)型是 BinaryOperator

記住一點(diǎn)很重要籽前,Lambda 表達(dá)式都可以擴(kuò)寫(xiě)為原始的“匿名類(lèi)”形式抵赢。所以當(dāng)你覺(jué)得這個(gè) Lambda 表達(dá)式很復(fù)雜不容易理解的時(shí)候,不妨把它擴(kuò)寫(xiě)為“匿名類(lèi)”形式來(lái)看这敬。

2.2 閉包

如果你以前使用過(guò)匿名內(nèi)部類(lèi),也許遇到過(guò)這樣的問(wèn)題蕉朵。當(dāng)你需要匿名內(nèi)部類(lèi)所在方法里的變量崔涂,必須把該變量聲明為final。如下例子所示:

final String name = getUserName();

button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event){? ? ? ? System.out.println("hi "+ name);? ? }});

Java 8放松了這一限制始衅,可以不必再把變量聲明為final冷蚂,但其實(shí)該變量實(shí)際上仍然是final的。雖然無(wú)需將變量聲明為 final汛闸,但在 Lambda 表達(dá)式中蝙茶,也無(wú)法用作非終態(tài)變量。如果堅(jiān)持用作非終態(tài)變量(即改變變量的值)诸老,編譯器就會(huì)報(bào)錯(cuò)隆夯。

2.3 函數(shù)接口

上面例子里提到了ActionListener接口,我們看一下它的代碼:

publicinterfaceActionListenerextendsEventListener{/**

? ? * Invoked when an action occurs.

? ? */publicvoidactionPerformed(ActionEvent e);}

ActionListener只有一個(gè)抽象方法:actionPerformed别伏,被用來(lái)表示行為:接受一個(gè)參數(shù)蹄衷,返回空。記住厘肮,由于actionPerformed定義在一個(gè)接口里愧口,因此abstract關(guān)鍵字不是必需的。該接口也繼承自一個(gè)不具有任何方法的父接口:EventListener轴脐。

我們把這種接口就叫做函數(shù)接口调卑。

JDK 8 中提供了一組常用的核心函數(shù)接口:

接口參數(shù)返回類(lèi)型描述

Predicate<T>Tboolean用于判別一個(gè)對(duì)象。比如求一個(gè)人是否為男性

Consumer<T>Tvoid用于接收一個(gè)對(duì)象進(jìn)行處理但沒(méi)有返回大咱,比如接收一個(gè)人并打印他的名字

Function<T, R>TR轉(zhuǎn)換一個(gè)對(duì)象為不同類(lèi)型的對(duì)象

Supplier<T>NoneT提供一個(gè)對(duì)象

UnaryOperator<T>TT接收對(duì)象并返回同類(lèi)型的對(duì)象

BinaryOperator<T>(T, T)T接收兩個(gè)同類(lèi)型的對(duì)象恬涧,并返回一個(gè)原類(lèi)型對(duì)象

其中Cosumer與Supplier對(duì)應(yīng),一個(gè)是消費(fèi)者碴巾,一個(gè)是提供者溯捆。

Predicate用于判斷對(duì)象是否符合某個(gè)條件,經(jīng)常被用來(lái)過(guò)濾對(duì)象。

Function是將一個(gè)對(duì)象轉(zhuǎn)換為另一個(gè)對(duì)象提揍,比如說(shuō)要裝箱或者拆箱某個(gè)對(duì)象啤月。

UnaryOperator接收和返回同類(lèi)型對(duì)象,一般用于對(duì)對(duì)象修改屬性劳跃。BinaryOperator則可以理解為合并對(duì)象谎仲。

如果以前接觸過(guò)一些其他 Java 框架,比如 Google Guava刨仑,可能已經(jīng)使用過(guò)這些接口郑诺,對(duì)這些東西并不陌生。所以杉武,其實(shí) Java 8 的改進(jìn)并不是閉門(mén)造車(chē)辙诞,而是集百家之長(zhǎng)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末飞涂,一起剝皮案震驚了整個(gè)濱河市祈搜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌泽西,老刑警劉巖缰趋,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秘血,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡仔涩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)熔脂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)霞揉,“玉大人,你說(shuō)我怎么就攤上這事适秩。” “怎么了骤公?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵阶捆,是天一觀的道長(zhǎng)钦听。 經(jīng)常有香客問(wèn)我,道長(zhǎng)彪见,這世上最難降的妖魔是什么余指? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任酵镜,我火速辦了婚禮柴钻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贴届。我一直安慰自己,他們只是感情好占键,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布畔乙。 她就那樣靜靜地躺著翩概,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钥庇。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,274評(píng)論 1 300
  • 那天皮服,我揣著相機(jī)與錄音龄广,去河邊找鬼。 笑死择同,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裹纳。 我是一名探鬼主播紧武,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼朋鞍!你這毒婦竟也來(lái)了妥箕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤坎吻,失蹤者是張志新(化名)和其女友劉穎宇葱,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體吗氏,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弦讽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年膀哲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仿村。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兴喂,死狀恐怖焚志,靈堂內(nèi)的尸體忽然破棺而出酱酬,到底是詐尸還是另有隱情,我是刑警寧澤膳沽,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布挑社,位于F島的核電站,受9級(jí)特大地震影響痛阻,放射性物質(zhì)發(fā)生泄漏腮敌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望动猬。 院中可真熱鬧,春花似錦钮莲、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至慈俯,卻和暖如春拥峦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背略号。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留突梦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓骚勘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親俏讹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子畜吊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

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