国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

imingyu / 697人閱讀

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

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

方法引用

形如:

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

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

Artist::getName
String::length

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

方法引用的類型

方法引用可以分為四類:

引用靜態方法: ClassName::staticMethodName, 比如: String.valueOf

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

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

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

元素順序

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

亂序

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

排序

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

無參的方法要求T實現了Comparable接口

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

收集器

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

轉換成集合

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

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

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

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

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

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

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

數據分割

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

數據分組

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

生成字符串

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

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

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

例一

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

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

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

例二

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

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

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

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

定制收集器

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

使用reduce方法

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

identity

accumulator

combiner

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

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

實現Collector接口

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

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

待收集元素的類型

累加器的類型

最終結果的類型

需要實現的方法有:

supplier: 生成初始容器

accumulator: 累加計算方法

combiner: 在并發流中合并容器

finisher: 將容器轉換成最終值

characteristics: 獲取特征集合

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

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

詳細講解可以參見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)

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

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

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

void forEach(BiConsumer action)

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

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

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/66626.html

相關文章

  • Java8實戰》-第六章讀書筆記(用流收集數據-01)

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

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

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

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

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

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

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

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

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

    NickZhou 評論0 收藏0

發表評論

0條評論

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