一葵孤、什么是函數(shù)式編程
? ? 函數(shù)式編程是一種編程范式鼻由,以函數(shù)作為第一對象暇榴。注重描述而非具體執(zhí)行步驟(比如SQL只聲明需要什么數(shù)據(jù)厚棵,具體數(shù)據(jù)庫怎么查沒指定)
二、特性
高階函數(shù)是指將一個或多個函數(shù)裝入一個另一個函數(shù)中蔼紧,這個函數(shù)會有相關(guān)操作并且返回一個全新的函數(shù)
三婆硬、應(yīng)用場景
比如創(chuàng)建線程只關(guān)心run()方法,但是JAVA8之前還是需要new Thread()和new Runnable()
四奸例、Lambda表達式
方法最重要的是方法簽名彬犯,那么可以有一個表達式——方法1 = (參數(shù),返回值) {干什么}查吊,Lambda表達式就是將返回值隱去之后得出的一個函數(shù)式
思考:a -> b -> c -> "d" 代表什么?
a的返回值是一個函數(shù)(b -> c -> ?"d"?)
b的返回值還是一個函數(shù)(?c ->??"d")
最后就是一個lambda表達式?c ->??"d"
它的意思是將a的入?yún)鬟f給b函數(shù)谐区,b函數(shù)將a入?yún)⒃賯鹘oc,c函數(shù)傳入入?yún)?zhí)行"d"操作返回最終結(jié)果值
輸入Integer返回一個Function<Integer逻卖,String>宋列,再將x+Integer作為String類型返回,比如傳入1评也,返回x1
4.1)引入lambda表達式后帶來的問題
4.2)函數(shù)式接口 SAM(Single Abstract Method)
4.3)內(nèi)置常用函數(shù)式接口
Supplier相當(dāng)于構(gòu)造函數(shù)只有返回沒有參數(shù)炼杖,Consumer有點像js中onClick(evt)方法只需要一個事件作為參數(shù)而不需要返回,Predicate用于if語句盗迟,UnaryOperator(高階函數(shù))指傳入一個函數(shù)返回一個新的函數(shù)
自定義三個參數(shù)一個返回值的函數(shù)式接口
4.4)函數(shù)的調(diào)用
可連續(xù)調(diào)用指第一個apply()方法返回的是一個Function<>坤邪,第二個apply()方法返回的是一個Consumer<>,第三個accept()方法返回的是一個Supplier<>
ff(String){
}
ff只是方法簽名中的方法名罚缕,既不是一種類型艇纺,也不是一個表達式
所以Function f = ff?這種編寫方式不可以怕磨,那如何將方法名ff進行使用呢
JAVA8提供了方法引用
4.5)方法引用????
五喂饥、函數(shù)接口轉(zhuǎn)換
六、CPS (continuation-passing style)
正常同步方法:
result1 = f1(String a); //方法f1執(zhí)行返回結(jié)果result1
void f2(result1); //方法f2傳入result1繼續(xù)下一步邏輯...
CPS常見的就是callback方法:
void f1(String a, Consumer<Object> callback); //f1()方法沒有返回值肠鲫,但是傳入?yún)?shù)a執(zhí)行后返回的結(jié)果會繼續(xù)傳遞給Object執(zhí)行下一個函數(shù)callback
七员帮、Stream
7.1)概述
流既然可以是無限的,那在操作StreamB變成StreamA的時候不代表系統(tǒng)已經(jīng)完全將StreamB中的元素按照我們lambda表達式的規(guī)則轉(zhuǎn)換好了放到StreamA中导饲,完全可能延遲處理
Source指獲得Stream實例捞高;Intermediate是對Stream所做的操作,可以有多個不同操作組裝最重要是filter和map/flatMAP渣锦;Terminal是獲得結(jié)果的操作
7.2)理解Stream.reduce()
理論上reduce可以替代一切for循環(huán)
7.3)reduce實戰(zhàn)? ??
將當(dāng)前對比的最大值作為累計值傳給下一個元素進行對比
在map映射中已經(jīng)將Integer轉(zhuǎn)換成了String
分段式處理具體操作在第二個入?yún)⒅羞M行描述
多個線程分段處理完后進行一個累計值操作(累計也看作reduce)就叫combiner
toListAccumulator()方法返回的就是一個高階函數(shù)
函數(shù)式編程的好處硝岗,比如方法不想拋異常:
f1 throw SQLException();
f1WithoutThrowExce(){
? ? try{
? ? ? ? f1();? ??
? ? }
}
假如來了一個f2,需要重新寫一個
f2WithoutThrowExce()袋毙;有了函數(shù)式編程之后可無限復(fù)用
fnWithoutThrowExce(Function<T, R> fn){
? ? return arg -> {
????????try{
? ? ????? ? fn.apply(arg);
? ? ????}
? ? }
}
7.4)理解Stream.collect()
reduce不應(yīng)該用來做toList()操作
第二個參數(shù)使用了
指定類型任意實例方法引用的少一個參數(shù)的特性型檀,將第一個入?yún)⑿陆ǖ腁rrayList進行了使用;第三個參數(shù)如下圖將分段的所有Container折疊成一個
Collector接口
Collector接口可以將本接口的四個函數(shù)組裝在一起
Collectors工具類
7.5)collect實戰(zhàn)
collectingAndThen()方法是先聚集然后進行下一步操作
八听盖、進階
8.1)函數(shù)組合
8.2)Optional
最重要的功能胀溺,Optional可以安全的一直map()下去裂七,而不用擔(dān)心變成空盒子的問題
8.3)flatMap()
扁平一層就是flatmap仓坞,Stream也有flatMap()處理Stream<Stream>
8.4)Functor & Monad