SlideShare a Scribd company logo
Submit Search
Upload
CH12:Lambda
Report
Justin Lin
Technology / Community Evangelist at Free lancer
Follow
•
0 likes
•
379 views
1
of
110
CH12:Lambda
•
0 likes
•
379 views
Download Now
Download to read offline
Report
Technology
認識Lambda語法 運用方法參考 瞭解介面預設方法 善用Functional與Stream API Lambda、平行化與非同步處理
Read more
Justin Lin
Technology / Community Evangelist at Free lancer
Follow
Recommended
CH09:Collection與Map
Justin Lin
288 views
•
87 slides
CH11:執行緒與並行API
Justin Lin
320 views
•
89 slides
CH1:Java平台概論
Justin Lin
1.2K views
•
41 slides
CH03:基礎語法
Justin Lin
528 views
•
48 slides
CH04:認識物件
Justin Lin
421 views
•
87 slides
Java SE 8 技術手冊第 12 章 - Lambda
Justin Lin
4.4K views
•
100 slides
More Related Content
Similar to CH12:Lambda
Java functional api
javakidxxx
290 views
•
20 slides
Java SE 8 技術手冊第 15 章 - 通用API
Justin Lin
2.2K views
•
82 slides
2014 Java Developer Day會後分享 Java Functional API
Anke Yang
613 views
•
24 slides
C#版本3~5的新特性
國昭 張
1.5K views
•
60 slides
Dpl in action
Pu Shiming
649 views
•
21 slides
Duck Typing and Multiple Inheritance
Sway Wang
379 views
•
46 slides
Similar to CH12:Lambda
(7)
Java functional api
javakidxxx
•
290 views
Java SE 8 技術手冊第 15 章 - 通用API
Justin Lin
•
2.2K views
2014 Java Developer Day會後分享 Java Functional API
Anke Yang
•
613 views
C#版本3~5的新特性
國昭 張
•
1.5K views
Dpl in action
Pu Shiming
•
649 views
Duck Typing and Multiple Inheritance
Sway Wang
•
379 views
Serverless api gateway + lambda
Leon Li
•
426 views
More from Justin Lin
Ch14 簡介 Spring Boot
Justin Lin
872 views
•
22 slides
Ch13 整合 Spring MVC/Security
Justin Lin
280 views
•
58 slides
Ch12 Spring 起步走
Justin Lin
273 views
•
31 slides
Ch11 簡介 JavaMail
Justin Lin
157 views
•
8 slides
Ch10 Web 容器安全管理
Justin Lin
153 views
•
30 slides
Ch09 整合資料庫
Justin Lin
233 views
•
92 slides
More from Justin Lin
(20)
Ch14 簡介 Spring Boot
Justin Lin
•
872 views
Ch13 整合 Spring MVC/Security
Justin Lin
•
280 views
Ch12 Spring 起步走
Justin Lin
•
273 views
Ch11 簡介 JavaMail
Justin Lin
•
157 views
Ch10 Web 容器安全管理
Justin Lin
•
153 views
Ch09 整合資料庫
Justin Lin
•
233 views
Ch08 自訂標籤
Justin Lin
•
133 views
Ch07 使用 JSTL
Justin Lin
•
161 views
Ch06 使用 JSP
Justin Lin
•
250 views
Ch05 Servlet 進階 API、過濾器與傾聽器
Justin Lin
•
204 views
Ch04 會話管理
Justin Lin
•
238 views
Ch03 請求與回應
Justin Lin
•
236 views
Ch02 撰寫與設定 Servlet
Justin Lin
•
352 views
CH1. 簡介 Web 應用程式
Justin Lin
•
1.2K views
14. 進階主題
Justin Lin
•
404 views
13.並行、平行與非同步
Justin Lin
•
237 views
12. 除錯、測試與效能
Justin Lin
•
153 views
11. 常用內建模組
Justin Lin
•
149 views
10. 資料永續與交換
Justin Lin
•
156 views
9. 資料結構
Justin Lin
•
292 views
CH12:Lambda
1.
1
2.
Lambda 學習目標 • 認識Lambda語法 • 運用方法參考 •
瞭解介面預設方法 • 善用Functional與Stream API • Lambda、平行化與非同步處理 2
3.
Lambda語法概覽 • 使用者名稱依長度排序 3
4.
• 使用Lambda表示式 4
5.
方法參考 5
6.
• 依名稱長度排序 • 重用既有方法實作,可避免到處寫下Lambda 運算式 6
7.
• 依字典順序排序名稱呢? 7
8.
• 按照字典順序排序,但忽略大小寫差異 • 方法參考不僅避免了重複撰寫Lambda運算式 ,還能讓程式碼更為清楚 8
9.
Lambda表示式與函式介面 • Lambda表示式(Expression) 9
10.
• 目標型態(Target type) •
Lambda表示式本身不代表任何型態的實例 10
11.
• Lambda沒有導入新型態來作為Lambda表示 式的型態 • 基於interface語法定義函式介面,作為表 示式的目標型態 –
要求僅具單一抽象方法 11
12.
• 匿名類別不是不好,只不過有其應用的場合 • 只想關心參數及實作本體 12
13.
• 只關心方法簽署的參數與回傳定義,然而忽 略方法名稱 13
14.
• interface語法做了演進,允許有預設方法 • 新標註@FunctionalInterface被引入 •
編譯錯誤 14
15.
Lambda遇上this與final 15
16.
• Lambda 表示式本體中this,來自Lambda 的周圍環境(Context) •
顯示兩次"Hello, World!" 16
17.
• 以下在JDK8以後不會有錯: • Lambda表示式不能修改捕獲的區域變數值 17
18.
方法與建構式參考 • 只要靜態方法的方法簽署中,參數與傳回值 定義相同,也可以使用靜態方法來定義函式 介面實作 18
19.
• 避免到處寫下Lambda表示式,儘量運用既有 的API實作,也可以改善可讀性 19
20.
• 函式介面實作可以參考靜態方法之外,還可 以參考特定物件的實例方法 20
21.
• 函式介面實作也可以參考類別定義的非靜態 方法,函式介面會試圖用第一個參數作為方 法接收者 21
22.
• 建構式參考可重用既有API的類別建構式 22
23.
介面預設方法 • 在JDK8以後,interface定義時可以有預 設實作 23
24.
• 預設方法必須使用default關鍵字修飾,預 設權限為public • 預設方法不能使用資料成員 24
25.
• 共用相同實作 25
26.
• 從JDK9開始,介面可以定義private方法 26
27.
辨別方法的實作版本 • 實作介面是廣義的多重繼承 • 介面也可以被繼承,而抽象方法或預設方法 都會繼承下來 •
子介面再以抽象方法重新定義父介面已定義 的抽象方法,通常是為了文件化 27
28.
• 父介面有個預設方法,子介面再度宣告與父 介面相同的方法簽署,但沒有寫出default • 子介面就直接重新定義該方法為抽象方法了 •
BiIterable的forEach()方法沒有實作了 28
29.
• 兩個父介面定義相同方法簽署的預設方法, 就會引發衝突 • 解決的方式是明確重新定義 –
假設Part與Canvas介面都定義了default的 draw()方法 29
30.
• 如果類別實作的兩個介面擁有相同的父介面 ,其中一個介面重新定義了父介面的預設方 法,而另一個介面沒有 – 實作類別會採用重新定義的版本 •
若子類別繼承了父類別同時又實作某介面, 而父類別的方法與介面中的預設方法具有相 同方法簽署 – 採用父類別的方法定義。 30
31.
• 簡單來說,類別的定義優先於介面的定義, 若有重新定義,就以重新定義為主,必要時 使用介面與super指定預設方法 31
32.
• JDK8除了讓介面可以定義預設方法,也允許 在介面中定義靜態方法 • 從JDK9開始,可以定義為private的靜態 方法 32
33.
Iterable • forEach()預設方法 33
34.
Iterator • forEachRemaining()的預設實作 34
35.
Comparator 35
36.
使用Optional取代null • Java Collection
API及JSR166參與者之一Doug Lea的話: • 圖靈獎得主、快速排序發明者Tony Hoare: 36 "Null sucks." "I call it my billion-dollar mistake."
37.
NullPointerException • null的根本問題在於語意含糊不清 – 可以是「不存在」、「沒有」、「無」或「空」 的概念 •
當開發者想到「嘿!這邊可以沒有東西…」 、「嗯!沒什麼東西可以傳回…」,就不假 思索地傳回null • 然後使用者就總是忘了檢查null,引發各種 可能的錯誤。 37
38.
• 確認使用null的時機與目的,使用明確語義 • 開發者於方法中傳回null,通常代表著客戶 端必須檢查是否為null,並在null的情況 下使用預設值 38
39.
39
40.
• 如果呼叫getNickName()時忘了檢查傳回 值,執行結果就會直接顯示null • 若後續的執行流程牽涉到至關重要的結果, 程式快樂地繼續執行下去,錯誤可能到某個 執行環節才會發生,造成不可預期的結果 40
41.
• getNickName()傳回Optional<String> • 方法若傳回Optional實例,表示該實例可 能包裹也可能不包裹值 41
42.
• 客戶端要意識到必須進行檢查,若不檢查就 直接呼叫Optional的get()方法: • java.util.NoSuchElementException ,這實現了速錯(Fail
fast)的概念 42
43.
• 使用orElse()方法,指定值不存在時的替 代值: 43
44.
• 程式庫無法說改就改,可使用Optional的 ofNullable()來銜接程式庫會傳回null 的方法 44
45.
標準API的函式介面 • Consumer • Function •
Predicate • Supplier 45
46.
Consumer函式介面 • 接受一個引數,處理後不傳回值 46
47.
• Iterable的forEach方法: 47
48.
• 對於基本型態有IntConsumer、 LongConsumer、DoubleConsumer • BiConsumer接受兩個物件作為引數的介面 •
還有ObjIntConsumer、 ObjLongConsumer、 ObjDoubleConsumer 48
49.
Function函式介面 • 接受一個引數,執行後傳回結果 • 就像數學函數y=f(x) 49
50.
• 子介面UnaryOperator,參數與傳回值都 是相同型態 • 基本型態的函式轉換,有IntFunction、 LongFunction、DoubleFunction、 IntToDoubleFunction、 IntToLongFunction… 50
51.
• 接受兩個引數、傳回一個結果 51
52.
Predicate函式介面 • 接受一個引數、傳回boolean值 52
53.
• BiPredicate接受兩個引數,傳回 boolean值 • 基本型態對應的函式介面,則有 IntPredicate、LongPredicate、 DoublePredicate 53
54.
Supplier函式介面 • 不接受任何引數就傳回值 54
55.
使用Stream進行管線操作 55
56.
• 管線(Pipeline)操作風格 • 惰性求值(Lazy
evaluation) – 外部迭代(External iteration) – 內部迭代(Internal iteration) 56
57.
• 絕大多數Stream不需要呼叫close()方法 • 除了一些I/O操作,例如Files.lines()、 Files.list()與Files.walk()方法 •
建議這類操作可以搭配嘗試關閉資源語法 57
58.
• 管線基本上包括了幾個部份: – 來源(Source) –
零或多個中介操作(Intermediate operation) – 一個最終操作(Terminal operation) 58
59.
59
60.
• 每個中介操作隱藏了細節,隱含了效率改進 的空間,也鼓勵開發者多利用這類風格 – 避免撰寫一些重複流程 –
思考目前的複雜演算中,實際上會是由哪些小任 務完成 60
61.
61
62.
• for迴圈若滲雜了許多小任務,會使for迴圈 中的程式碼艱澀難懂 • Stream只能迭代一次 62
63.
Stream的reduce與collect • 求得一組員工的男性平均年齡: 63
64.
• 求得一組員工的男性最大年齡: 64
65.
• 類似的流程結構 • 從閱讀程式碼角度來看,無法一眼察覺程式 意圖 65
66.
66
67.
67
68.
68
69.
• 將男性員工收集至另一個List<Employee> • Collector主要的四個方法: –
supplier() – accumulator() – combiner() – finisher() 69
70.
70
71.
71
72.
72
73.
73
74.
關於flatMap()方法 • 巢狀或瀑布式的流程 74
75.
75
76.
• 將Optional<T>轉換為Optional<U>的方 式可由外部指定 76
77.
77
78.
• flatMap()就像從盒子取出另一盒子(flat 是平坦化的意思) • Lambda表示式指定了前一盒子的值與下個盒 子間的轉換關係 •
避免巢狀或瀑布式的複雜檢查流程 78
79.
• 若沒辦法修改傳回Optional型態怎麼辦? 79
80.
80
81.
81
82.
Stream相關API • Arrays的stream() • Stream、IntStream、DoubleStream等 都有of()靜態方法,也各有generate()與 iterate()靜態方法 •
IntStream有range()與rangeClosed() 82
83.
• CharSequence新增chars()與 codePoints() • java.util.Random類別 83
84.
Optional的API增強 84
85.
85
86.
86
87.
Stream的API增強 87
88.
• 若試著運行底下程式,會從x為4開始迭代: • 若想設定迭代中止的條件: 88
89.
• takeWhile()與dropWhile()方法 89
90.
Stream與平行化 • 想獲得平行處理能力 • Java在API的設計上,希望你進行平行處理 時,能有明確的語義 90
91.
• 不代表就會平行處理而使得執行必然變快 • 必須思考處理過程是否能夠分而治之而後合 併結果 91
92.
• Stream實例若具有平行處理能力,處理過程 會試著分而治之 92
93.
• 希望最後順序是照著原來Stream來源的順序 • 使用forEachOrdered()這類有序處理時 ,可能會失去平行化部份(甚至全部)優勢 •
有些中介操作亦有可能發生類似情況,例如 sorted()方法 93
94.
• API文件基本上會記載終結操作時是否依來 源順序 94
95.
• 在collect()操作時若想有平行效果,必須 符合以下三個條件: – Stream必須有平行處理能力。 –
Collector必須有 Collector.Characteristics.CONCURREN T特性。 – Stream是無序或者Collector具有 Collector.Characteristics.UNORDERED 特性。 95
96.
• API在處理小任務時,不應該進行干擾 • 會引發ConcurrentModifiedException 96
97.
• 思考目前任務是由哪些小任務組成 97
98.
• 一次只做一件事 98
99.
• 避免寫出以下的程式: 99
100.
• 這樣的程式不僅不易理解,若試圖進行平行 化處理時: • added10s的順序並不照著numbers的順序 100
101.
• 一次處理一個任務的版本,可以簡單地改為 平行化版本,又沒有順序問題: 101
102.
Arrays與平行化 • 針對超長陣列的平行化操作,Arrays新增: – parallelPrefix() –
parallelSetAll() – parallelSort() 102
103.
CompletableFuture 103
104.
• 回呼(Callback)風格 • 回呼地獄(Callback
hell) 104
105.
105
106.
• 若第一個CompletableFuture任務完成後 ,想繼續以非同步方式處理結果 106
107.
• CompletableFuture也有個 thenCompose()(以及非同步的 thenComposeAsnyc()版本),作用就類 似flatMap() 107
108.
CompletableFuture增強 108
109.
109
110.
110