java 8 函式式程式設計實戰

2021-09-11 07:14:23 字數 3582 閱讀 4072

函式一二三等值的區分:

只要某個值滿足以下三個條件,就能被稱為一等值。

可以作為引數傳遞給函式

可以作為函式返回值

可以被賦值給變數

所以數字、字串等常用的值都是一等的。如果僅滿足第一條,而不能作為函式返回值或被賦值給變數,就稱為二等的(second-class)。假如三條都不滿足,則稱為三等的(third-class)。

謂詞:在數學上常用來表示乙個類似函式的東西,接受乙個引數,並返回true或false。

函式式介面:只定義乙個抽象方法的介面。哪怕介面定義了很多預設方法,只要介面之定義了乙個抽象方法,它就仍然是乙個函式時介面

@functionalinte***ce 表示該介面會設計成乙個函式式介面,但不是必須的,但對於為此設計的介面而言,使用它是比較好的做法。
如果lambda表示式丟擲乙個異常,那麼抽象方法所生命的throws語句也必須與之匹配。

特殊的 void 相容規則:

如果乙個 lambda 的主體是乙個語句表示式, 它就和乙個返回 void 的函式描述符相容(當然需要引數列表也相容)。例如,以下兩行都是合法的,儘管list的add方法返回了乙個boolean,而不是consumer上下文(t -> void)所要求的void:

// predicate返回了乙個boolean

predicatep = s -> list.add(s);

// consumer返回了乙個void

consumerb = s -> list.add(s);

原始型別流特化:

為了避免暗含的裝箱成本(int和integer之間效率差異)

提供了intstream,doublestream,longstream的介面。

使用maptoint()這類方法變成intstream

使用boxed()方法變為物件流stream型別

同樣的optional也有optionalint optionallong optionaldouble三種型別

可以使用靜態方法stream.of建立乙個流

stream.empty()得到乙個空流
files.lines()檔案中使用返回乙個流

集合api collection主要為了儲存和訪問資料,stream主要用於描述對資料的計算,集合講的是資料,流講的是計算。stream允許並提倡並行處理乙個stream中的元素。

流的資料處理支援列斯資料庫的操作以及函式式程式語言的常用操作。

流就是從支援資料處理操作的源生成的元素序列。

很多流操作本身返回乙個流,這樣可以多個操作連線起來形成乙個大的流水線,這樣就可以優化產生如:延遲和短路。

流水線操作可看作對資料來源進行資料庫式的查詢。

從有序集合生成流時會保留原有的順序,有列表生成流,其元素順序與列表一致。

流是在概念上固定的資料結構(不能刪除或者新增元素),只會按需生成,延遲建立的集合們只有在消費者需要才會計算值。

集合是急切建立的。如建立乙個包含所有質數的流。

流只能遍歷一次。再次使用就會拋異常說流已經被使用了。

流是內部迭代的,專案透明的並行處理,或用更優化的順序進行處理。

若果使用集合collection外部迭代(使用者去做迭代)都得自己優化是很困難的。

除非流水線上觸發乙個終端操作,否則中間操作不執行任何處理。因為中間操作都可以合併起來,在終端一次性全部處理。

終端操作 從流生成結果其結果是任何不是流的值。

流一般做的三件事:

乙個資料來源執行乙個查詢

乙個中間操作鏈,形成一條流水線

乙個終端操作,執行流水線,並形成結果。

流的limit(n)返回乙個不超過給定長度的流與skip(n)返回一扔掉前n個元素的流(若元素不足n則返回乙個空流)是互補的。

map()接受乙個函式為引數,該函式被應用到每個元素上,並將其對映(建立乙個新版本)成乙個新元素。

faltmap():流的扁平化,讓你把流中的每個值度換成另乙個流,然後把所有的流連起來成為乙個流。

anymatch()流中是否有乙個元素能匹配給定謂詞。(短路或||)返回boolean終端操作

allmatch()流中元素是否都能匹配給定謂詞(短路與&&)返回boolean終端操作

nonematch()流中沒有任何元素與給定謂詞匹配。返回boolean終端操作

findany()終端操作 返回當前流中的任意元素。

findfirst()返回流**現的第乙個元素

為何同時有findany和findfirst,因為並行,找第乙個元素在並行上限制更多,所以不關心返回元素是哪個則使用findany因為並行時使用限制少。

t reduce(t identity, binaryoperatoraccumulator);
identity初始值

accumulator 將兩個元素結合產生乙個新值。如lambda (a,b) -> a+b;

如下:numbers是乙個集合

int sum = numbers.stream().reduce(0, (a,b) -> a*b);

也可以使用其過載版本不輸入初始值。但會返回乙個optional物件:

optionalreduce(binaryoperatoraccumulator);
當然也可以計算最大值最小值

listnumbers = arrays.aslist(3,4,5,1,2);

int sum = numbers.stream().reduce(0, (a, b) -> a + b);

system.out.println(sum);

int sum2 = numbers.stream().reduce(0, integer::sum);

system.out.println(sum2);

int max = numbers.stream().reduce(0, (a, b) -> integer.max(a, b));

system.out.println(max);

optionalmin = numbers.stream().reduce(integer::min);

integer::min等價於 lambda(x,y)-> x

min.ifpresent(system.out::println);

int calories = menu.stream()

.map(dish::getcalories)

.reduce(0, integer::sum);

system.out.println("number of calories:" + calories);

java8函式式程式設計(二)

list常用操作 private static list init 迴圈列印集合中每個元素 private static void foreach private static void tolist 計算集合中age 4的元素個數 private static void filter 篩選出顏色為...

初探java8函式式程式設計

lambda引用的是值,不是變數,所以,lambda中引用變數,必須是final變數或者既成事實上的final變數 collect tolist 方法由stream 裡的值生成乙個列表,是乙個及早求值操作 listcollected stream.of a b c collect collector...

java 8 函式式介面

functionalinte ce public inte ce personsearch functionalinte ce public inte ce personsearch1 functionalinte ce public inte ce personsearch2 方法的預設實現 介面...