摘要:本文是函數式編程第三章的讀書筆記,章名為流。正確使用表達式明確要達成什么轉化,而不是說明如何轉化沒有副作用只通過函數的返回值就能充分理解函數的全部作用函數不會修改程序或外界的狀態獲取值而不是變量避免使用數組逃過的追殺,應該考慮優化邏輯
本文是「Java 8 函數式編程」第三章的讀書筆記,章名為流。本章主要介紹了外部迭代與內部迭代以及常用的高階函數。
外部迭代與內部迭代 外部迭代過去我們要對一個List進行迭代時,往往會采用如下方式:
int count = 0; for (Artist artist : artists) { if (artist.isFrom("London")) { count++; } }
而這種方法的原理,其實是先調用iterator方法,然后再迭代,等效于如下代碼:
int count = 0; Iteratoriterator = artists.iterator(); while (iterator.hasNext()) { Artist artist = iterator.next(); if (artist.isFrom("London")) { count++; } }
這樣的迭代方式,把迭代的控制權交給了iterator對象,讓其控制整個迭代過程,這就叫做外部迭代。
外部迭代需要我們自己編寫迭代的控制代碼,顯得十分繁瑣。特別是對于Map對象,繁瑣到我都不想給出例子。
外部迭代將行為和方法混為一談,難以對代碼進行重構操作。
內部迭代與之相對的就是內部迭代了。內部迭代就是把迭代的控制權交給了集合本身,讓集合自己實現相應的迭代,而調用者并不需要關心如何迭代。
要使用內部迭代,需要使用Java 8中新增的接口Stream。而集合框架都已經包含了一個stream()方法,用于獲得Stream對象。
long count = artists.stream() .filter(artist -> artist.isFrom("London")) .count();
這個例子就是使用的內部迭代。先獲取stream對象,然后調用filter方法過濾,最后統計符合條件的個數。
實現機制在Java中調用一個方法,通常會立即執行操作。然而Stream里的一些方法卻不太一樣,它們返回的對象不是新的集合,而是創建新集合的配方。我們通過一個例子說明:
Streamnames = Stream.of("Bryant", "Jordon", "James") .filter(name -> { System.out.println(name); return name.length() == 6; }); System.out.println("counting"); System.out.println(names.count());
最終會得到如下輸出:
counting Bryant Jordon James 2
出現這樣的結果,原因是
像filter這樣的方法,只會描述Stream,最終不會產生新集合的方法叫做惰性求值方法
像count這樣會從Stream中產生值或集合等結果的方法叫做及早求值方法
判斷一個操作是惰性求值還是及早求值,只需要看它的返回值
如果返回值是Stream,則是惰性求值
返回的是一個值或null,則是及早求值
在對集合使用流操作時,使用惰性求值方法形成一個惰性求值的鏈,最后用及早求值方法得到結果,而集合只需要迭代一次。
常用流操作collect:及早求值,常用于生成List Map或其他復雜的數據結構
map:惰性求值,將一種類型的數據轉換成另一種類型,將一個流中的值轉化成一個新的流,類似于Hadoop里的map
filter:惰性求值,過濾不符合條件的元素
flatMap:惰性求值,類似于map,只是Function參數的返回值限定為Stream,用于連接多個Stream成為一個Stream
max & min:及早求值,reduce方法的特例,返回Optional(第四章介紹)對象
reduce:及早求值,從一組值中生成一個值,類似于Hadoop中的reduce
高階函數高階函數接收一個函數作為參數,或者返回一個函數的函數。
正確使用Lambda表達式明確要達成什么轉化,而不是說明如何轉化
沒有副作用:
只通過函數的返回值就能充分理解函數的全部作用
函數不會修改程序或外界的狀態
獲取值而不是變量(避免使用數組逃過JVM的追殺,應該考慮優化邏輯)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66602.html
摘要:限制編寫并行流,存在一些與非并行流不一樣的約定。底層框架并行流在底層沿用的框架,遞歸式的分解問題,然后每段并行執行,最終由合并結果,返回最后的值。 本書第六章的讀書筆記,也是我這個系列的最后一篇讀書筆記。后面7、8、9章分別講的測試、調試與重構、設計和架構的原則以及使用Lambda表達式編寫并發程序,因為筆記不好整理,就不寫了,感興趣的同學自己買書來看吧。 并行化流操作 關于并行與并發...
摘要:第四章引入流一什么是流流是的新成員,它允許你以聲明性方式處理數據集合通過查詢語句來表達,而不是臨時編寫一個實現。 第四章 引入流 一、什么是流 流是Java API的新成員,它允許你以聲明性方式處理數據集合(通過查詢語句來表達,而不是臨時編寫一個實現)。就現在來說,你可以把它們看成遍歷數據集的高級迭代器。此外,流還可以透明地并行處理,你無需寫任何多線程代碼。 下面兩段代碼都是用來返回低...
摘要:收集器用作高級歸約剛剛的結論又引出了優秀的函數式設計的另一個好處更易復合和重用。更具體地說,對流調用方法將對流中的元素觸發一個歸約操作由來參數化。另一個常見的返回單個值的歸約操作是對流中對象的一個數值字段求和。 用流收集數據 我們在前一章中學到,流可以用類似于數據庫的操作幫助你處理集合。你可以把Java 8的流看作花哨又懶惰的數據集迭代器。它們支持兩種類型的操作:中間操作(如 filt...
摘要:但是,最好使用差異化的類型定義,函數簽名如下其實二者說的是同一件事。后者的返回值和初始函數的返回值相同,即。破壞式更新和函數式更新的比較三的延遲計算的設計者們在將引入時采取了比較特殊的方式。四匹配模式語言中暫時并未提供這一特性,略。 一、無處不在的函數 一等函數:能夠像普通變量一樣使用的函數稱為一等函數(first-class function)通過::操作符,你可以創建一個方法引用,...
摘要:本文是函數式編程第二章的讀書筆記。的語法簡化了使用匿名內部類時的模板代碼,讓程序員專注于編寫想要執行的行為,也讓代碼更加簡潔易讀。中最重要的函數接口類型推斷為新成員表達式提供了類型推斷的支持,在不需要聲明參數類型的表達式中表現的有為明顯。 本文是「Java 8 函數式編程」第二章的讀書筆記。 Lambda引入的變化 Lambda表達式,是一種緊湊的、傳遞行為的方式,從編程思想上來講,...
閱讀 1052·2021-10-11 10:59
閱讀 3605·2021-09-26 09:55
閱讀 897·2019-08-30 15:55
閱讀 2653·2019-08-30 15:44
閱讀 438·2019-08-30 14:06
閱讀 685·2019-08-30 11:26
閱讀 3342·2019-08-30 10:49
閱讀 2481·2019-08-29 12:53