摘要:本章是該書的第五章主要講了方法引用和收集器方法引用形如這樣的表達(dá)式可以簡(jiǎn)寫為這種簡(jiǎn)寫的語(yǔ)法被稱為方法引用方法引用無(wú)需考慮參數(shù)因?yàn)橐粋€(gè)方法引用可以在不同的情況下解析為不同的表達(dá)式這依賴于的推斷方法引用的類型方法引用可以分為四類引用靜態(tài)方法
本章是該書的第五章, 主要講了方法引用和收集器
方法引用形如:
artist -> artist.getName() (String arg) -> arg.length()
這樣的表達(dá)式, 可以簡(jiǎn)寫為:
Artist::getName String::length
這種簡(jiǎn)寫的語(yǔ)法被稱為方法引用. 方法引用無(wú)需考慮參數(shù), 因?yàn)橐粋€(gè)方法引用可以在不同的情況下解析為不同的Lambda表達(dá)式, 這依賴于JVM的推斷.
方法引用的類型方法引用可以分為四類:
引用靜態(tài)方法: ClassName::staticMethodName, 比如: String.valueOf
引用特定實(shí)例方法: object::instanceMethodName, 比如: str::toString
引用特定類型的任意對(duì)象的實(shí)例方法: ClassName::instanceMethodName, 比如: String::length
引用構(gòu)造方法: ClassName::new, 比如: String::new
元素順序當(dāng)我們對(duì)集合進(jìn)行操作時(shí), 有時(shí)希望是按照一定的順序來操作, 而有時(shí)又希望是亂序的操作. 有兩個(gè)方法可以幫助我們進(jìn)行順序的操作.
亂序BaseStream.unordered()方法可以打亂順序, 科技將本來有序的集合變成無(wú)序的集合
排序Stream.sorted方法有兩個(gè)簽名, 一個(gè)無(wú)參, 一個(gè)有參數(shù)Comparator super T> comparator
無(wú)參的方法要求T實(shí)現(xiàn)了Comparable接口
有參方法需要提供一個(gè)比較器
收集器收集器是一種通用的, 從流中生成復(fù)雜值的結(jié)構(gòu). 將其傳給collect方法, 所有的流就都可以使用它. 而下面提到的單個(gè)收集器, 都可以使用reduce方法模擬.
轉(zhuǎn)換成集合我們可以使用Collectors中的靜態(tài)方法toList() toSet()等, 將流收集為List或Set
stream.collect(toList()) stream.collect(toSet())
我們不需要關(guān)心具體使用的是哪一種具體的實(shí)現(xiàn), Stream類庫(kù)會(huì)為我們選擇. 因?yàn)槲覀兛梢岳?b>Stream進(jìn)行并行數(shù)據(jù)處理, 所以選擇是否線程安全的集合十分重要.
當(dāng)然我們也可以指定使用哪一種實(shí)現(xiàn)來進(jìn)行收集:
stream.collect(toCollection(ArrayList::new))轉(zhuǎn)換成值
Collectors類提供了很多的方法用于轉(zhuǎn)化值, 比如counting maxBy minBy等等, 可以查看javadoc了解.
目前了解到的是, 這三個(gè)方法都可以使用Stream中的count max min方法代替, 而不需要作為collect方法的參數(shù)
數(shù)據(jù)分割有時(shí)我們想按照一個(gè)條件把數(shù)據(jù)分成兩個(gè)部分, 而不是只獲取符合條件的部分, 這時(shí)可以使用partitioningBy方法收集. 將它傳入collect方法, 可以得到一個(gè)Map
groupingBy方法可以將流分成多個(gè)List, 而不僅僅是兩個(gè), 接收一個(gè)Lambda表達(dá)式作為參數(shù), 其返回值作為key, 最后的結(jié)果也是一個(gè)Map, 形如Map
如果要從流中得到字符串, 可以在得到Stream
artists.stream() .map(Artist::getName) .collect(Collectors.joining(",", "[", "]"));組合收集器
我們可以將收集器組合起來, 達(dá)到更強(qiáng)的功能. 書上舉了兩個(gè)栗子
例一
public MapnumberOfAlbums(Stream albums) { return albums .collect( groupingBy(Album::getMainMusicina, counting())); }
這個(gè)方法的目的是統(tǒng)計(jì)每個(gè)歌手的作品數(shù)目. 如果不組合收集器, 我們先用groupingBy得到一個(gè)Map
上面的counting方法類似于count方法, 作用于List
例二
public Map> nameOfAlbums(Stream albums) { return albums .collect( groupingBy(Album::getMainMusician, mapping(Album::getName, toList()))); }
這個(gè)方法的目的是得到每個(gè)歌手的作品名稱列表. 如果不組合收集器, 我們將會(huì)先得到一個(gè)Map
mapping收集器的功能類似于map, 將一種類型的流轉(zhuǎn)換成另一種類型. 所以類似的, mapping并不知道要把結(jié)果收集成什么數(shù)據(jù)結(jié)構(gòu), 它的第二個(gè)參數(shù)就會(huì)接收一個(gè)普通的收集器, 比如這里的toList, 來完成收集.
這里的counting和mapping是我們用到的第二個(gè)收集器, 用于收集最終結(jié)果的一個(gè)子集, 這些收集器叫做下游收集器.
定制收集器定制收集器看起來麻煩, 其實(shí)抓住要點(diǎn)就行了.
使用reduce方法前面說過, 這些收集器都可以使用reduce方法實(shí)現(xiàn), 我們定制收集器, 實(shí)際上就是為reduce方法編寫三個(gè)參數(shù), 分別是:
identity
accumulator
combiner
關(guān)于這三個(gè)參數(shù)的意義, 如果不太理解, 可以看看這個(gè)答案: https://segmentfault.com/q/1010000004944450
我們可以設(shè)計(jì)一個(gè)類, 為這三個(gè)參數(shù)設(shè)計(jì)三個(gè)方法, 再提供一個(gè)方法用于獲取目標(biāo)類型(如果這個(gè)類就是目標(biāo)類型的話, 可以不提供這個(gè)方法)
實(shí)現(xiàn)Collector接口如果不想顯式的使用reduce方法, 我們只需要提供一個(gè)類, 實(shí)現(xiàn)Collector接口.
該接口需要三個(gè)泛型參數(shù), 依次是:
待收集元素的類型
累加器的類型
最終結(jié)果的類型
需要實(shí)現(xiàn)的方法有:
supplier: 生成初始容器
accumulator: 累加計(jì)算方法
combiner: 在并發(fā)流中合并容器
finisher: 將容器轉(zhuǎn)換成最終值
characteristics: 獲取特征集合
多數(shù)情況下, 我們的容器器和我們的目標(biāo)類型并不一致, 這時(shí), 需要實(shí)現(xiàn)finisher方法將容器轉(zhuǎn)化為目標(biāo)類型, 比如調(diào)用容器的toString方法.
有時(shí)我們的目標(biāo)類型就是我們的容器, finisher方法就不需要對(duì)容器做任何操作, 而是通過設(shè)置characteristics為IDENTITY_FINISH, 使用框架提供的優(yōu)化得到結(jié)果.
詳細(xì)講解可以參見http://irusist.github.io/2016/01/04/Java-8%E4%B9%8BCollector/
Map新增方法Java 8為Map新增了很多方法, 可以通過搜索引擎輕松找到相關(guān)文章. 這里舉幾個(gè)書中提到的相關(guān)方法.
V computeIfAbsent(K key, Function super K, ? extends V> mappingFunction)
V computeIfPresent(K key, BiFunction super K, ? super V, extends V> remappingFunction)
V compute(K key, BiFunction super K, ? super V, ? extends V> remappingFunction)
這三個(gè)方法類似, 都是根據(jù)key來處理, 只是Lambda表達(dá)式的執(zhí)行條件不同, 從函數(shù)名就可以看出來. 不過要注意Lambda表達(dá)式的參數(shù), 第一個(gè)方法的Lambda只需要一個(gè)參數(shù)key, 后面兩個(gè)方法的Lambda需要兩個(gè)參數(shù)key和value, 而compute方法的Lambda中的value參數(shù)可能為null.
V merge(K key, V value, BiFunction super V, ? super V, ? extends V> remappingFunction)
此方法用于合并value, 新value在第二個(gè)參數(shù)給出. Lambda表達(dá)式規(guī)定合并方法, 其兩個(gè)參數(shù)依次是oldValue和newValue, oldValue是原Map的value, 可能為空; newValue為merge方法的第二個(gè)參數(shù).
void forEach(BiConsumer super K, ? super V> action)
通過forEach方法, 不再需要使用外部迭代來遍歷Map.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/66626.html
摘要:收集器用作高級(jí)歸約剛剛的結(jié)論又引出了優(yōu)秀的函數(shù)式設(shè)計(jì)的另一個(gè)好處更易復(fù)合和重用。更具體地說,對(duì)流調(diào)用方法將對(duì)流中的元素觸發(fā)一個(gè)歸約操作由來參數(shù)化。另一個(gè)常見的返回單個(gè)值的歸約操作是對(duì)流中對(duì)象的一個(gè)數(shù)值字段求和。 用流收集數(shù)據(jù) 我們?cè)谇耙徽轮袑W(xué)到,流可以用類似于數(shù)據(jù)庫(kù)的操作幫助你處理集合。你可以把Java 8的流看作花哨又懶惰的數(shù)據(jù)集迭代器。它們支持兩種類型的操作:中間操作(如 filt...
摘要:第四章引入流一什么是流流是的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合通過查詢語(yǔ)句來表達(dá),而不是臨時(shí)編寫一個(gè)實(shí)現(xiàn)。 第四章 引入流 一、什么是流 流是Java API的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合(通過查詢語(yǔ)句來表達(dá),而不是臨時(shí)編寫一個(gè)實(shí)現(xiàn))。就現(xiàn)在來說,你可以把它們看成遍歷數(shù)據(jù)集的高級(jí)迭代器。此外,流還可以透明地并行處理,你無(wú)需寫任何多線程代碼。 下面兩段代碼都是用來返回低...
摘要:本文是函數(shù)式編程第三章的讀書筆記,章名為流。正確使用表達(dá)式明確要達(dá)成什么轉(zhuǎn)化,而不是說明如何轉(zhuǎn)化沒有副作用只通過函數(shù)的返回值就能充分理解函數(shù)的全部作用函數(shù)不會(huì)修改程序或外界的狀態(tài)獲取值而不是變量避免使用數(shù)組逃過的追殺,應(yīng)該考慮優(yōu)化邏輯 本文是「Java 8 函數(shù)式編程」第三章的讀書筆記,章名為流。本章主要介紹了外部迭代與內(nèi)部迭代以及常用的高階函數(shù)。 外部迭代與內(nèi)部迭代 外部迭代 過去我...
摘要:新特性總覽標(biāo)簽本文主要介紹的新特性,包括表達(dá)式方法引用流默認(rèn)方法組合式異步編程新的時(shí)間,等等各個(gè)方面。還有對(duì)應(yīng)的和類型的函數(shù)連接字符串廣義的歸約匯總起始值,映射方法,二元結(jié)合二元結(jié)合。使用并行流時(shí)要注意避免共享可變狀態(tài)。 Java8新特性總覽 標(biāo)簽: java [TOC] 本文主要介紹 Java 8 的新特性,包括 Lambda 表達(dá)式、方法引用、流(Stream API)、默認(rèn)方...
摘要:而面向?qū)ο髣t是向程序員提供表示問題空間中元素的工具,我們將問題空間中的元素及其在解空間中的表示稱為對(duì)象。為什么要把對(duì)象看作是服務(wù)提供者呢這是將問題分解為對(duì)象集合的一種合理方式。職能太多,可能會(huì)導(dǎo)致對(duì)象的內(nèi)聚性降低。在試圖將子類對(duì)象當(dāng)作其基類 計(jì)算機(jī)是頭腦延伸的工具,是一種不同類型的表達(dá)媒體。本文以背景性的和補(bǔ)充性的材料,介紹包括開發(fā)方法概述在內(nèi)的面向?qū)ο蟪绦蛟O(shè)計(jì)(Object-orie...
閱讀 804·2021-11-17 09:33
閱讀 3851·2021-09-01 10:46
閱讀 1842·2019-08-30 11:02
閱讀 3354·2019-08-29 15:05
閱讀 1451·2019-08-26 11:39
閱讀 2354·2019-08-23 17:04
閱讀 2031·2019-08-23 15:43
閱讀 1423·2019-08-23 14:12