Lambda 學習目標 認識Lambda語法 運用方法參考 瞭解介面預設方法 善用Functional與Stream API

Slides:



Advertisements
Similar presentations
JAVA 编 程 技 术 主编 贾振华 2010年1月.
Advertisements

消費者委員會 研究及商營手法事務主任 麥詠詩女士
消費者委員會 研究及商營手法事務主任 麥詠詩女士
生涯不卡關 ~生涯卡之簡介與實務應用 吳慧美.
企業之採購管理 周惠文 教授 國立中央大學資訊管理學系
第 4 章 PHP 基本語法.
第一章 資料結構導論 1-1 資料結構簡介 1-2 認識程式設計 1-3 演算法效能分析 1-4 物件導向程式設計與Java.
An Introduction to Database Systems
朝陽國小學校課程發表簡報 活力四年級 導師:蔡于晨.
Lua+wax在ios上的应用 白 衣.
第一組成員 蕭毓文(1號) :內壢高中 范美珍(4號) :平鎮高中 林宏茂(6號) :中壢高中 林桂鳳(18號) :竹北高中
算法设计与分析 Algorithm Design and Analysis
OUTLINE Android app Devolpment Flow App反組譯解說 實例 簽名詳解 DalvikByteCode
第一部 认识篇 知己知彼 百战不殆.
ES6简介.
程設一.
什麼是教育行動研究 ◎從例子中發現 行動研究的特色為何?.
科學科 污染 空氣 成因 的 : 題目 及 減少空氣污染的方法 陳玉玲 (4) 姓名 : 去到目錄.
你愛/礙到我了-- 談親密關係與身體界線 左營高中 家政教師 李麗凰
Ch07 PHP程式基礎 網頁程式設計.
Design Pattern (2) 设计模式(2) Institute of Computer Software 2018/9/21
程設一.
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
第5章 面向对象程序设计 本章要点 5.1 面向对象程序设计概述 5.2 Java语言的面向对象程序设计 5.3 方法的使用和对象数组
物件導向程式設計 (Object-Oriented rogramming)
Classes Lecturer: 曾學文.
第六章 类的扩展与继承.
程式敘述執行順序的轉移 控制與重複、方法 Lecturer:曾學文.
第3章 語法入門 第一個Java程式 文字模式下與程式互動 資料、運算 流程控制.
第 7 章 陣列 (Array).
本單元介紹何謂變數,及說明變數的宣告方式。
导入 STL的概念与组成 Iterator(迭代器) Container(容器) Algorithm(算法) Adaptors(配接器)
第9章 類別圖與物件圖 9-1 類別圖與物件圖的基礎 9-2 類別圖的符號 9-3 類別關係 9-4 物件圖 9-5 繪製類別圖與物件圖
Java程序设计 第9章 继承和多态.
【STL標準樣版函式庫】 STL(Standard Template Library),即標準樣版函式庫,是一個具有工業標準、高效率的C++函式庫。它包含於C++標準函式庫(C++ Standard Library)中,是ANSI/ISO C++標準中,最新的、也是極具革命性的一部分。STL包含了諸多在電腦科學領域裏所常用的基本資料結構和基本演算法。為廣大C++程式師們提供了一個可擴展的應用框架,高度實現了軟體的可複用性。這種現象有些類似於Microsoft.
DWR WEB开发交流 1、自我介绍 2、DWR概述 3、DWR DEMO介绍 4、DWR实现机制 5、DWR配置说明 6、JS开发注意事项.
變數命名 保留字(Reserved Word)
蔡哲民 信望愛聖經網站董事與技術組負責人 崑山科技大學資訊傳播系助理教授
郑晟 昆明理工大学 云南省计算机技术应用重点实验室
2019/1/16 Java语言程序设计-类与对象 教师:段鹏飞.
2019/1/17 Java语言程序设计-程序流程 教师:段鹏飞.
Java程序设计 第2章 基本数据类型及操作.
Spark SQL 介绍 付士涛. Spark SQL 介绍 付士涛 大纲 Architecture(架构) 像Hive一样的User Interface(用户操作界面) DataFrame的使用(1.3以前叫做SchemaRDD)
Introduction to lisp lisp.
第7章 繼承/多型/介面 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或供拷貝.
Java集合.
第3章 Java語法的JSP程式 3-1 Java語言的基礎 3-2 JSP程式的基本架構 3-3 Java的變數與資料型態
JAVA 编 程 技 术 主编 贾振华 2010年1月.
软件测试 (四)静态测试与动态测试.
《JAVA程序设计》 语音答疑 辅导老师:高旻.
第五章 介面/集合/泛型 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或供拷貝.
陳維魁 博士 儒林圖書公司 第三章 變數與繫結 陳維魁 博士 儒林圖書公司.
第二章 Java基本语法 讲师:复凡.
Action Script 使用介紹 第六組 張瀚之.
一个实体浏览系统中书签管理模块的设计与实现
第二章 Java语法基础.

第二章 Java基本语法 讲师:复凡.
本节内容 Lua基本语法.
宜蘭縣教師會 《第三屆super教師獎》遴選簡報
第二章 Java基本语法 讲师:复凡.
方法進階及物件導向基礎 Lecturer: 楊昌樺.
第4章 数组与字符串 学习目标 本章要点 上机练习 习 题.
职位评估—解决内部薪酬的公平性 薪酬设计地图.
并行计算 Parallel Computing 方匡南 厦门大学教授 博士生导师.
第2章 Java语言基础.
資料結構 老師:李崇明 助教:楊斯竣.
104 四技二專甄選入學 簡章解析 輔導室 何乙娟.
第二章 Java基础语法 北京传智播客教育
6 集合类与泛型.
Presentation transcript:

Lambda 學習目標 認識Lambda語法 運用方法參考 瞭解介面預設方法 善用Functional與Stream API

Lambda語法概覽 匿名類別的應用場合

Lambda語法概覽 稍微改變Arrays.sort()該行的可讀性

Lambda語法概覽 使用JDK8的Lambda表示式 編譯器可以從byLength變數的宣告型態,name1與name2的型態

Lambda語法概覽 直接放到Arrays的sort()方法中

Lambda語法概覽 將一些字串排序時可能的方式都定義出來

Lambda語法概覽 原本的依名稱長度排序就可以改寫為: JDK8 提供了方法參考(Method reference)

Lambda語法概覽 方法參考的特性,在重用現有API上扮演了重要角色。重用現有方法實作,可避免到處寫下Lambda運算式

Lambda語法概覽 byLexicography()方法實作中,只不過是呼叫String的compareTo()方法

Lambda語法概覽 想對名稱按照字典順序排序,但忽略大小寫差異 方法參考不僅避免了重複撰寫Lambda運算式,也可以讓程式碼更為清楚

Lambda表示式與函式介面 等號右邊是Lambda表示式(Expression),等號左邊是作為Lambda表示式的目標型態(Target type)

Lambda表示式與函式介面 Lambda表示式:

Lambda表示式與函式介面 如果有目標型態的話,在編譯器可推斷出類型的情況下,就可以不寫出Lambda表示式的參數型態

Lambda表示式與函式介面 函式介面就是介面,要求僅具單一抽象方法

Lambda表示式與函式介面 匿名類別不是不好,只不過有其應用的場合 在許多時候,特別是介面只有一個方法要實作時,你會只想關心參數及實作本體

Lambda表示式與函式介面 如果函式介面上定義的方法只接受一個參數

Lambda表示式與函式介面 @FunctionalInterface在JDK8中被引入 並非函式介面的話會編譯錯誤,例如:

Lambda遇上this與final Lambda表示式並不是匿名類別的語法蜜糖

Lambda遇上this與final

Lambda遇上this與final

Lambda遇上this與final 以下在JDK8中不會有錯:

Lambda遇上this與final 如果Lambda表示式中捕獲的區域變數本身等效於final區域變數,可以不用在區域變數上加上final。 可以在Lambda表示式中改變被捕獲的區域變數值嗎?答案是不行!

方法與建構式參考 可以使用靜態方法來定義函式介面實作

方法與建構式參考 方法參考(Method references)可以避免你到處寫下Lambda表示式,儘量運用現有的API實作,也可以改善可讀性

方法與建構式參考 可以參考特定物件的實例方法

方法與建構式參考 可以參考類別上定義的非靜態方法

方法與建構式參考 建構式參考(Constructor references)用來重用現有API的物件建構流程

介面預設方法 在JDK8中,interface定義時可以加入預設實作,或者稱為預設方法(Default methods)

介面預設方法 forEach()方法本身已有實作,所以不會破壞Iterable現有的其他實作 預設方法中不能使用資料成員 預設方法中不能有直接變更狀態的流程

介面預設方法 JDK8新增了預設方法,這也給了共用相同實作的方便性

介面預設方法 如果有個Ball類別打算實作這個自定義的Comparable介面的話

介面預設方法 實作介面是廣義的多重繼承 JDK8中允許有預設實作,引入了強大的威力,也引入了更多的複雜度 你得留意到底採用的是哪個方法版本

介面預設方法 父介面中的抽象方法,可以在子介面中以預設方法實作 父介面中的預設方法,可以在子介面中被新的預設方法重新定義 重新定義父類別中預設方法實作為抽象方法

介面預設方法 如果重新定義為預設方法時,想明確呼叫某個父介面的draw()方法,必須使用介面名稱與super明確指定

介面預設方法 如果實作時有兩個介面都定義了相同方法簽署的預設方法,那麼會引發衝突 解決的方式是明確重新定義,無論是重新定義為抽象或預設方法 如果重新定義為具體方法時,想明呼叫某個介面的方法,也是得使用介面名稱與super明確指定

介面預設方法 如果類別實作的兩個介面擁有相同的父介面,其中一個介面重新定義了父介面的預設方法,而另一個介面沒有,那麼實作類別會採用重新定義了的版本 如果子類別繼承了父類別同時實作某介面,而父類別中的方法與介面中的預設方法具有相同方法簽署,則採用父類別的方法定義

介面預設方法 簡單來說,類別中的定義優先於介面中的定義,如果有重新定義,就以重新定義的為主,必要時使用介面與super指定採用哪個預設方法 JDK8除了讓介面可以定義預設方法之外,也開始允許在介面中定義靜態方法

介面預設方法 Iterable介面新增forEach()預設方法:

介面預設方法 Iterator也有個forEachRemaining()的預設實作

介面預設方法 Comparator也定義了一些預設方法

使用Optional取代null 你經常會與NullPointerException奮戰 null的最根本問題在於語意含糊不清

使用Optional取代null 呼叫方法時如果傳回型態是Optional,應該立即想到它可能包裹也可能不包裹值

使用Optional取代null 在Optional沒有包含值的情況下,get會拋出NoSuchElementException

使用Optional取代null Optional的ofNullable()來銜接程式庫中會傳回null的方法

標準API的函式介面 JDK8已經定義了幾個通用的函式介面 基本上可以分為Consumer、Function、Predicate與Supplier四個類型

標準API的函式介面 如果需要的行為是接受一個引數,然後處理後不傳回值,就可以使用Consumer介面

標準API的函式介面 接受了引數但沒有傳回值,這行為就像純綷消耗了引數,就是命名為Consumer的原因 真的有結果產生,就是以副作用(Side effect)形式呈現

標準API的函式介面 接受一個引數,然後以該引數進行計算後傳回結果,就可以使用Function介面 行為就像是數學函數y=f(x),給予x值計算出y值的概念,因此命名為Function

標準API的函式介面 接受一個引數,然後只傳回boolean值,也就是根據傳入的引數直接論斷真假的行為,就可以使用Predicate函式介面

標準API的函式介面 需要的行為是不接受任何引數,然後傳回值,那可以使用Supplier函式介面

使用Stream進行管線操作 在正式瞭解Stream介面的作用之前

使用Stream進行管線操作 在JDK8中,這類的需求,建議改用以下的程式來完成:

使用Stream進行管線操作 能夠達到這類惰性求值(Lazy evaluation)的效果,功臣就是Stream實例 第一個程式片段搭配for迴圈進行外部迭代(External iteration)第二個程式片段內部迭代(Internal iteration) 因為內部迭代的行為是被隱藏的,因此多了很多可以實現效率的可能性。

使用Stream進行管線操作 絕大多數的Stream並不需要呼叫close()方法 JDK8中要close()的是Files.lines()、Files.list()與Files.walk()方法

使用Stream進行管線操作 JDK8引入了Stream API,也引入了管線操作風格 來源(Source) 零或多個中介操作(Intermediate operation) 一個最終操作(Terminal operation)

使用Stream進行管線操作 原本有個程式片段:

使用Stream進行管線操作 在JDK8中可以改為以下的風格:

使用Stream進行管線操作 如果你的程式在for迴圈中使用了if:

使用Stream進行管線操作 如果你的程式在for迴圈中從一個型態對應至另一個型態:

使用Stream進行管線操作 許多時候,for迴圈中就是滲雜了許多小任務,從而使for迴圈中的程式碼艱澀難懂 Stream只能迭代一次,重複對Stream進行迭代,會引發IllegalStateException

Stream的reduce與collect 程式設計中不少地方存在類似需求

Stream的reduce與collect 程式中這類需求都存在著類似的流程結構,而你也不斷重複撰寫著類似結構,而且從閱讀程式碼角度來看,無法一眼察覺程式意圖

Stream的reduce與collect 在JDK8中,可以改寫為:

Stream的reduce與collect 先前的迴圈結構,實際上有個步驟都是將一組數據逐步取出削減,然而透過指定運算以取得結果的結構 JDK8將這個流程結構通用化,定義了reduce()方法來達到自訂運算需求

Stream的reduce與collect

Stream的reduce與collect 如果你想將一組員工的男性收集至另一個List<Employee>呢?

Stream的reduce與collect Collector主要的四個方法是: suppiler()傳回Suppiler,定義收集結果的新容器如何建立 accumulator()傳回BiConsumer,定義如何使用結果容器收集物件 combiner()傳回BinaryOperator,定義若有兩個結果容器,如何合併為一個結果容器 finisher()傳回Function,選擇性地定義如何將結果轉換為最後的結果容器。

Stream的reduce與collect 來看看Stream的collect()方法另一版本

Stream的reduce與collect 可以先看看Collectors上提供了哪些Collector實作

Stream的reduce與collect

關於flatMap()方法 在程式設計中有時會出現巢狀或瀑布式的流程,就結構來看每一層運算極為類似,只是傳回的型態不同,很難抽取流程重用

關於flatMap()方法 巢狀的層次可能還會更深,像是 ...

關於flatMap()方法 如果能修改getCustomer()傳回Optional<Customer>、也修改getAddress()傳回Optional<String>

關於flatMap()方法 每一層都是Optional型態了,而每一層都是isPresent()的判斷,然後將Optional<T>轉換為Optional<U>

關於flatMap()方法 直接使用Optional的flatMap()方法: 第二個程式片段,改寫為以下就清楚多了…

關於flatMap()方法 flatMap()就像是從盒子取出另一盒子(flat就是平坦化的意思) Lambda表示式指定了前一個盒子中的值與下一個盒子之間的轉換關係 運算情境被隱藏了,使用者可明確指定感興趣的特定運算,從而使程式碼意圖顯露出來 可接暢地接續運算,以避免巢狀或瀑布式的複雜檢查流程。

關於flatMap()方法 如果你沒辦法修改傳回型態怎麼辦?

關於flatMap()方法 連續取得List

關於flatMap()方法 用List的stream()方法取得Stream之後,使用flatMap()方法

關於flatMap()方法 從盒子中取出盒子的操作(一個Stream接著一個Stream)可以接續下去

關於flatMap()方法 如果能瞭解Optional、Stream(或其他型態)的flatMap()方法,其實就是取得盒子中的值,讓你指定這個值與下個盒子間的關係,那在撰寫與閱讀程式碼時,忽略掉flatMap這個名稱,就能比較清楚程式碼的主要意圖

Stream與平行化 要獲得平行處理能力在JDK8中可以說很簡單

Stream與平行化 JDK8希望你想要進行平行處理時,必須有明確的語義 想要知道Stream是否為平行處理,可以呼叫isParallel()來得知

Stream與平行化 天下沒有白吃的午餐 留意平行處理時的順序需求 不要干擾Stream來源 一次做一件事

Stream與平行化 使用了parallelStream(),不代表一定會平行處理而使得執行必然變快 得思考處理過程是否能夠分而治之而後合併結果,如果可能,方能從中獲益

Stream與平行化 Collectors有groupingBy()與groupingByConcurrent()

Stream與平行化 Stream實例若具有平行處理能力,處理過程會分而治之

Stream與平行化 使用forEachOrdered()這類的有序處理時,可能會(或完全失去)失去平行化的一些優勢 實際上中介操作亦有可能如此,例如sorted()方法 API文件上基本上會記載終結操作時是否依來源順序

Stream與平行化 reduce()基本上是按照來源順序,而collect()得視給予的Collector而定

Stream與平行化 在collect()操作時若想要有平行效果 Stream必須有平行處理能力。 Collector必須有Collector.Characteristics.CONCURRENT特性。 Stream是無序的(Unordered)或Collector具Collector.Characteristics.UNORDERED特性。

Stream與平行化 當API在處理小任務時,你不應該進行干擾 這樣的程式會引發ConcurrentModifiedException

Stream與平行化 思考處理的過程中,實際上是由哪些小任務組成

Stream與平行化 記得一次只做一件事

Stream與平行化 避免寫出以下的程式:

Stream與平行化 如果你試圖進行平行化處理時,就會發現,alsoLt的順序並不照著numbers的順序 然而一次處理一個任務的版本,可以簡單地改為平行化版本,而又沒有順序問題

使用CompletableFuture 非同步(Asynchronous)讀取文字檔案

使用CompletableFuture 回呼地獄(Callback hell)

使用CompletableFuture JDK8新增了CompletableFuture

使用CompletableFuture 繼續以非同步方式來處理結果