天天看點

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

簡介

Oracle在2014年3月份釋出了java8正式版,該版本增加了很多新特性,比如:函數式接口、lambda表達式、集合的流式操作、注解的更新、安全性增強、IO\NIO的改進

函數式接口

什麼是函數式接口

這是java8的一個核心概念,(Functional Interfaces).通過在接口中添加一個抽象方法,這些方法可以直接從接口中運作。我們有兩種方法去實作一個函數式接口 

1. 在一個接口中定義唯一一個抽象方法,那麼這個接口就成為函數式接口 

2. 通過注解@functionalInterface,用來标注這個接口是一個函數式接口。推薦這種寫法,好處是如果接口不符合函數式接口的定義時,編譯器會報錯 

Java.lang.Runnable就是一個典型的函數式接口;

函數式接口的用途

主要用在Lambda表達式和方法引用上

代碼示範

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

函數式接口的特性

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作
  1. 函數式接口允許定義靜态方法
  2. 函數式接口允許定義default方法
  3. 函數式接口裡允許定義java.lang.Object裡的public方法 

泛型及繼承關系

接口可以繼承接口,如果一個父接口是一個函數接口,那麼子接口也有可能是一個函數式接口,那麼它的判斷依據是什麼呢? 

對于接口I, 假定M是接口成員裡的所有抽象方法的繼承(包括繼承于父接口的方法), 除去具有和Object的public的執行個體方法簽名的方法, 那麼我們可以依據下面的條件判斷一個接口是否是函數式接口, 這樣可以更精确的定義函數式接口。 

如果存在一個一個方法m, 滿足: 

• m的簽名(subsignature)是M中每一個方法簽名的子簽名(signature) 

• m的傳回值類型是M中的每一個方法的傳回值類型的替代類型(return-type-substitutable) 

那麼I就是一個函數式接口。

情況一

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

接口Z繼承了X,Y接口的m方法,由于這兩個方法的簽名相同,傳回值也一樣,是以Z有唯一的一個抽象方法int m(List arg);,可以作為函數式接口。

情況二

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

方法簽名Y.m既滿足簽名是X.m,并且傳回值也滿足,是以Z仍然是函數式接口

情況三

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

編譯出錯,因為沒有一個方法的簽名是所有方法的子簽名

Java.util.function

Lambda表達式在運作期間表示為一個接口函數,而接口函數隻是一種隻定義了一個抽象方法的接口。盡管java8裡面已經有一些接口符合函數式接口的定義,比如Runnable , Comparator。但是對于我們來說顯然是不夠的。而如果我們需要在程式裡使用非函數數接口來實作lambda表達式的操作,那麼怎麼去做? Java8引入了一個新增的包java.util.function, 專門用來解決這個問題。這個包裡提供了很多接口 

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

Lambda表達式

函數式接口的重要屬性是:我們能夠使用Lambda來執行個體化他們,Lambda表達式讓你能夠将函數廢棄方法參數,或者将代碼作為資料對待。

優點

在java8出現之前,匿名内部類,監聽器和事件處理的使用都顯得很冗長,代碼可讀性差,而Lambda表達式的應用能夠是代碼變得更加緊湊,可讀性增強

文法

Lambda表達式由三個部分組成: 

第一部分:一個括号内用逗号分割形式參數,參數是函數式接口裡面方法的參數 

第二部分:一個箭頭号 -> 

第三部分:方法體,可以是表達式和代碼塊

情況一

方法體為表達式,則該表達式的值作為傳回值傳回: 

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

情況二

方法體為代碼塊,必須要用{}包裹起來,如果該接口有傳回值,則需要return傳回值,反之則不需要 

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

代碼示範

情況1, 對内部類進行簡化 

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

情況2,我們用list排序來示範效果 

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

簡化處理後

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

方法引用

有時候Lambda表達式的代碼隻是一個簡單的方法調用而已,而遇到另外一種情況我們可以更進一步去簡化,我們稱之為方法引用;

引用靜态方法

引用對象的執行個體方法

引用某個類型的任意對象的執行個體方法

引用類構造函數

代碼示範 

我們同樣針對一個數組進行排序,綜合以上所有提到的方法引用類型 

第一步 

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

第二步 

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

第三步 

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

集合流式操作

Java8引入了流式操作(Stream),通過該操作可以實作對集合的并行處理和函數式操作。 

1. 根據操作傳回的結果不同,流式操作又分為中間操作和最終操作。最終操作傳回的是一個特定類型的結果;而中間操作傳回的是流本身,是以就可以将多個操作一次串聯起來; 

2. 根據流的并發性、又可以分為串行和并行兩種,流式操作實作了對集合的過濾、排序、映射等功能

串行流和并行流

通過串行流操作是在一個線程中依次完成,而并行流則是在多個線程上同時執行。并行和串行的流操作可以互相切換:通過 

Stream.sequential()傳回串行流 

Stream.parallel() 傳回并行流 

相比于串行流,并行流可以很大程度上提高程式的執行效率 

串行/并行排序示範 

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

中間操作

該操作會保持 stream 處于中間狀态,允許做進一步的操作。它傳回的還是的 Stream,允許更多的鍊式操作。常見的中間操作有: 

filter():對元素進行過濾; 

sorted():對元素排序; 

map():元素的映射; 

distinct():去除重複元素; 

subStream():擷取子 Stream 等。

終止操作

該操作必須是流的最後一個操作,一旦被調用,Stream 就到了一個終止狀态,該操作之後不能再鍊式的添加其他操作。常見的終止操作有: 

forEach():對每個元素做處理; 

toArray():把元素導出到數組; 

findFirst():傳回第一個比對的元素; 

anyMatch():是否有比對的元素等。

788692365阿裡P8在此群,可以在這裡和他進行java進階、架構方面的經驗學習交流。

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作

另有咕泡Java架構VIP七夕520告白金抽取機會

JAVA8的新特性詳解簡介函數式接口Java.util.functionLambda表達式集合流式操作