成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

「Java 8 函數(shù)式編程」讀書筆記——高級集合類和收集器

imingyu / 700人閱讀

摘要:本章是該書的第五章主要講了方法引用和收集器方法引用形如這樣的表達式可以簡寫為這種簡寫的語法被稱為方法引用方法引用無需考慮參數(shù)因為一個方法引用可以在不同的情況下解析為不同的表達式這依賴于的推斷方法引用的類型方法引用可以分為四類引用靜態(tài)方法

本章是該書的第五章, 主要講了方法引用和收集器

方法引用

形如:

artist -> artist.getName()
(String arg) -> arg.length()

這樣的表達式, 可以簡寫為:

Artist::getName
String::length

這種簡寫的語法被稱為方法引用. 方法引用無需考慮參數(shù), 因為一個方法引用可以在不同的情況下解析為不同的Lambda表達式, 這依賴于JVM的推斷.

方法引用的類型

方法引用可以分為四類:

引用靜態(tài)方法: ClassName::staticMethodName, 比如: String.valueOf

引用特定實例方法: object::instanceMethodName, 比如: str::toString

引用特定類型的任意對象的實例方法: ClassName::instanceMethodName, 比如: String::length

引用構造方法: ClassName::new, 比如: String::new

元素順序

當我們對集合進行操作時, 有時希望是按照一定的順序來操作, 而有時又希望是亂序的操作. 有兩個方法可以幫助我們進行順序的操作.

亂序

BaseStream.unordered()方法可以打亂順序, 科技將本來有序的集合變成無序的集合

排序

Stream.sorted方法有兩個簽名, 一個無參, 一個有參數(shù)Comparator comparator

無參的方法要求T實現(xiàn)了Comparable接口

有參方法需要提供一個比較器

收集器

收集器是一種通用的, 從流中生成復雜值的結構. 將其傳給collect方法, 所有的流就都可以使用它. 而下面提到的單個收集器, 都可以使用reduce方法模擬.

轉換成集合

我們可以使用Collectors中的靜態(tài)方法toList() toSet()等, 將流收集為ListSet

stream.collect(toList())
stream.collect(toSet())

我們不需要關心具體使用的是哪一種具體的實現(xiàn), Stream類庫會為我們選擇. 因為我們可以利用Stream進行并行數(shù)據(jù)處理, 所以選擇是否線程安全的集合十分重要.

當然我們也可以指定使用哪一種實現(xiàn)來進行收集:

stream.collect(toCollection(ArrayList::new))
轉換成值

Collectors類提供了很多的方法用于轉化值, 比如counting maxBy minBy等等, 可以查看javadoc了解.

目前了解到的是, 這三個方法都可以使用Stream中的count max min方法代替, 而不需要作為collect方法的參數(shù)

數(shù)據(jù)分割

有時我們想按照一個條件把數(shù)據(jù)分成兩個部分, 而不是只獲取符合條件的部分, 這時可以使用partitioningBy方法收集. 將它傳入collect方法, 可以得到一個Map, 然后就可以對相應的數(shù)據(jù)進行處理了.

數(shù)據(jù)分組

groupingBy方法可以將流分成多個List, 而不僅僅是兩個, 接收一個Lambda表達式作為參數(shù), 其返回值作為key, 最后的結果也是一個Map, 形如Map. 這一方法類似于SQL中的group by

生成字符串

如果要從流中得到字符串, 可以在得到Stream之后使用Collectors.joining方法收集. 該方法接收3個String參數(shù), 分別是分隔符 前綴 后綴

artists.stream()
  .map(Artist::getName)
  .collect(Collectors.joining(",", "[", "]"));
組合收集器

我們可以將收集器組合起來, 達到更強的功能. 書上舉了兩個栗子

例一

public Map numberOfAlbums(Stream albums) {
  return albums
    .collect(
    groupingBy(Album::getMainMusicina, counting()));
}

這個方法的目的是統(tǒng)計每個歌手的作品數(shù)目. 如果不組合收集器, 我們先用groupingBy得到一個Map>之后, 還要去遍歷Map得到統(tǒng)計數(shù)目, 增加了代碼量和性能開銷.

上面的counting方法類似于count方法, 作用于List的流上.

例二

public Map> nameOfAlbums(Stream albums) {
  return albums
    .collect(
    groupingBy(Album::getMainMusician,
              mapping(Album::getName, toList())));
}

這個方法的目的是得到每個歌手的作品名稱列表. 如果不組合收集器, 我們將會先得到一個Map>. 然而, 我們只想得到作品名稱, 也就是一個List, 組合mapping收集器可以幫助我們實現(xiàn)效果.

mapping收集器的功能類似于map, 將一種類型的流轉換成另一種類型. 所以類似的, mapping并不知道要把結果收集成什么數(shù)據(jù)結構, 它的第二個參數(shù)就會接收一個普通的收集器, 比如這里的toList, 來完成收集.

這里的countingmapping是我們用到的第二個收集器, 用于收集最終結果的一個子集, 這些收集器叫做下游收集器.

定制收集器

定制收集器看起來麻煩, 其實抓住要點就行了.

使用reduce方法

前面說過, 這些收集器都可以使用reduce方法實現(xiàn), 我們定制收集器, 實際上就是為reduce方法編寫三個參數(shù), 分別是:

identity

accumulator

combiner

關于這三個參數(shù)的意義, 如果不太理解, 可以看看這個答案: https://segmentfault.com/q/1010000004944450

我們可以設計一個類, 為這三個參數(shù)設計三個方法, 再提供一個方法用于獲取目標類型(如果這個類就是目標類型的話, 可以不提供這個方法)

實現(xiàn)Collector接口

如果不想顯式的使用reduce方法, 我們只需要提供一個類, 實現(xiàn)Collector接口.

該接口需要三個泛型參數(shù), 依次是:

待收集元素的類型

累加器的類型

最終結果的類型

需要實現(xiàn)的方法有:

supplier: 生成初始容器

accumulator: 累加計算方法

combiner: 在并發(fā)流中合并容器

finisher: 將容器轉換成最終值

characteristics: 獲取特征集合

多數(shù)情況下, 我們的容器器和我們的目標類型并不一致, 這時, 需要實現(xiàn)finisher方法將容器轉化為目標類型, 比如調用容器的toString方法.

有時我們的目標類型就是我們的容器, finisher方法就不需要對容器做任何操作, 而是通過設置characteristicsIDENTITY_FINISH, 使用框架提供的優(yōu)化得到結果.

詳細講解可以參見http://irusist.github.io/2016/01/04/Java-8%E4%B9%8BCollector/

Map新增方法

Java 8Map新增了很多方法, 可以通過搜索引擎輕松找到相關文章. 這里舉幾個書中提到的相關方法.

V computeIfAbsent(K key, Function mappingFunction)

V computeIfPresent(K key, BiFunction remappingFunction)

V compute(K key, BiFunction remappingFunction)

這三個方法類似, 都是根據(jù)key來處理, 只是Lambda表達式的執(zhí)行條件不同, 從函數(shù)名就可以看出來. 不過要注意Lambda表達式的參數(shù), 第一個方法的Lambda只需要一個參數(shù)key, 后面兩個方法的Lambda需要兩個參數(shù)keyvalue, 而compute方法的Lambda中的value參數(shù)可能為null.

V merge(K key, V value, BiFunction remappingFunction)

此方法用于合并value, 新value在第二個參數(shù)給出. Lambda表達式規(guī)定合并方法, 其兩個參數(shù)依次是oldValuenewValue, oldValue是原Mapvalue, 可能為空; newValuemerge方法的第二個參數(shù).

void forEach(BiConsumer action)

通過forEach方法, 不再需要使用外部迭代來遍歷Map.

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/66626.html

相關文章

  • Java8實戰(zhàn)》-第六章讀書筆記(用流收集數(shù)據(jù)-01)

    摘要:收集器用作高級歸約剛剛的結論又引出了優(yōu)秀的函數(shù)式設計的另一個好處更易復合和重用。更具體地說,對流調用方法將對流中的元素觸發(fā)一個歸約操作由來參數(shù)化。另一個常見的返回單個值的歸約操作是對流中對象的一個數(shù)值字段求和。 用流收集數(shù)據(jù) 我們在前一章中學到,流可以用類似于數(shù)據(jù)庫的操作幫助你處理集合。你可以把Java 8的流看作花哨又懶惰的數(shù)據(jù)集迭代器。它們支持兩種類型的操作:中間操作(如 filt...

    EscapedDog 評論0 收藏0
  • java 8 實戰(zhàn)》讀書筆記 -第四章 引入流

    摘要:第四章引入流一什么是流流是的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合通過查詢語句來表達,而不是臨時編寫一個實現(xiàn)。 第四章 引入流 一、什么是流 流是Java API的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合(通過查詢語句來表達,而不是臨時編寫一個實現(xiàn))。就現(xiàn)在來說,你可以把它們看成遍歷數(shù)據(jù)集的高級迭代器。此外,流還可以透明地并行處理,你無需寫任何多線程代碼。 下面兩段代碼都是用來返回低...

    jeyhan 評論0 收藏0
  • Java 8 函數(shù)編程讀書筆記——流

    摘要:本文是函數(shù)式編程第三章的讀書筆記,章名為流。正確使用表達式明確要達成什么轉化,而不是說明如何轉化沒有副作用只通過函數(shù)的返回值就能充分理解函數(shù)的全部作用函數(shù)不會修改程序或外界的狀態(tài)獲取值而不是變量避免使用數(shù)組逃過的追殺,應該考慮優(yōu)化邏輯 本文是「Java 8 函數(shù)式編程」第三章的讀書筆記,章名為流。本章主要介紹了外部迭代與內部迭代以及常用的高階函數(shù)。 外部迭代與內部迭代 外部迭代 過去我...

    qpwoeiru96 評論0 收藏0
  • Java8新特性總覽

    摘要:新特性總覽標簽本文主要介紹的新特性,包括表達式方法引用流默認方法組合式異步編程新的時間,等等各個方面。還有對應的和類型的函數(shù)連接字符串廣義的歸約匯總起始值,映射方法,二元結合二元結合。使用并行流時要注意避免共享可變狀態(tài)。 Java8新特性總覽 標簽: java [TOC] 本文主要介紹 Java 8 的新特性,包括 Lambda 表達式、方法引用、流(Stream API)、默認方...

    mayaohua 評論0 收藏0
  • Java編程思想》讀書筆記-對象導論

    摘要:而面向對象則是向程序員提供表示問題空間中元素的工具,我們將問題空間中的元素及其在解空間中的表示稱為對象。為什么要把對象看作是服務提供者呢這是將問題分解為對象集合的一種合理方式。職能太多,可能會導致對象的內聚性降低。在試圖將子類對象當作其基類 計算機是頭腦延伸的工具,是一種不同類型的表達媒體。本文以背景性的和補充性的材料,介紹包括開發(fā)方法概述在內的面向對象程序設計(Object-orie...

    NickZhou 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<