今天抽點時間對jdk8寫個總體的學習總結,一來當作乙個覆盤加深理解,二來也希望能夠對閱讀的朋友們有一點點幫助,同時也希望大家對文中不準確的內容予以指出。
1、函式式介面與lambda表示式
首先說一下函式式介面的概念:
介面中的抽象方法如果是重寫了object類的方法的話,是不參與計數的
另外如果乙個介面是函式式介面,那麼無論我是否打上functionalinte***ce註解它都是函式式介面,而打上functionalinte***ce註解僅僅是用來按函式式介面的要求來檢測該介面。
然後來說說lambda表示式:
lambda表示式是用來建立函式式介面例項的一種方式,當然你也可以使用匿名內部類、或者實現該介面的類來例項化物件,但lambda表示式顯然更為簡潔,最簡單的格式如下:
(arg) ->
arg代表抽象方法的引數,body代表抽象方法的實現,為了更形象的闡述,我們舉個例子,比如runnable介面,在jdk8中就是乙個函式式介面,那麼我們可以通過如下**來理解:
new thread( new runnable() ).start();
這是匿名內部類的實現方式,下面我們使用lambda表示式:
new thread( ()-> ).start();
只要寫好對應的實現即可。這部分我還想額外說一下,之前很長一段時間我一直認為lambda表示式是匿名內部類實現的一種語法糖,可現實並非如此,我們將抽象方法的實現改為system.out.println(this);,發現匿名內部類列印的是匿名內部類的乙個例項物件,而lambda表示式中的this就是當前物件本身,所以可以說lambda表示式和匿名內部類並沒有什麼關係,只是實現了相同的功能而已。
2、高階函式
在了解了函式式介面和lambda表示式之後,很顯然,我們發現lambda表示式可以作為函式的乙個載體進行傳遞,由此產生了高階函式的概念:
如果乙個函式接收乙個函式作為引數,或者返回乙個函式作為返回值,那麼該函式就叫做高階函式
3、方法引用
方法引用可以理解為lambda表示式的一種語法糖,是lambda表示式某些特化情況下的一種簡化替換,具體來講就是當lambda表示式的實現只有一行語句時,可以按如下規則進行替換:
類名::靜態方法名 ----- 這種情況就是說這一行語句是呼叫了某個類的靜態方法,而抽象方法的引數會傳遞給靜態方法的引數
引用名(物件名)::例項方法名 ------ 這種情況是呼叫了例項的方法,引數傳遞同上
類名::例項方法名 ---- 這種情況代表抽象方法的引數列表的第乙個引數作為例項方法的呼叫者,其餘引數作為呼叫引數
類名::new ------ 這種情況代表返回類名對應的乙個例項,抽象方法的引數會傳遞給構造方法
對於方法引用這種語法糖可能剛開始看的時候感覺不適應,而且它等於說是一種簡化替換,但是為了閱讀他人以及底層的源**能夠讀得懂,還是有必要適應一下的。
4、介面規則變動
與之前版本不同的是對於jdk8的介面是可以有方法實現的,分別是靜態方法和預設方法,靜態方法和我們之前定義的類似,通過類名加點的方式即可呼叫,預設方法通過default關鍵字來定義,需要例項化物件之後才能呼叫,這兩種方法的出現很大程度上的原因是在於增加了新特性之後仍然能夠相容老版本**的一種解決方案,可以讓我們的專案平滑的公升級到jdk8。
5、內建api函式式支援
jdk8之後,特別是集合框架增加了一些基於內建函式式介面的api,例如list的sort方法:
default
void
sort
(comparator c)
}
再比如iterable的foreach方法:
default
void
foreach
(consumer action)
}
comparator介面在jdk8中很顯然符合函式式介面的要求,我們可以通過傳入乙個lambda表示式到sort函式,代表排序的規則。對於foreach方法我們發現他定義在了iterable介面當中,這代表所有實現了可迭代介面的集合框架類都會繼承到這個預設方法,通過預設方法這種方式就解決了在增加新特性,同時基本又不對現有**做大變動的問題,foreach方法接收的是乙個consumer介面,它代表接收乙個引數不返回結果,原始碼如下:
@functionalinte***ce
public
inte***ce
consumer
; }
}
這裡是兩個常用簡單的例子,起乙個拋磚引玉的作用。
6、stream api
這部分內容我認為算是新特性中比較核心的內容了,它支援以流的方式操縱集合資料,可以執行一些例如過濾、轉換、分組、聚合等操作,底層實現也是比較複雜的,從流源構造,將集合的迭代器,或者是集合的陣列放入分割迭代器中,然後經過多種中間操作,到最後的終止操作,完成運算,對於多種中間操作,其底層實現採用的是雙向鍊錶將多個運算連線起來,但是並不會執行運算,在終止操作時才會執行從後向前的巢狀呼叫,然後再從前向後一級級返回。如果終止操作是乙個收集操作,那麼又會涉及到收集器的概念,乙個收集器包括中間結果容器提供者supplier函式式介面,累加操作biconsumer函式式介面,合併容器操作binaryoperator函式式介面,完成器function函式式介面以及乙個描述元資料的屬性集合,如果大家感興趣的話可以讀一下具體的原始碼,這裡僅僅簡單描述一下流程。
這裡就先粗淺的寫一些大方向上的內容,原始碼細節上以後有時間再逐個往出整理,今天暫時先寫到這裡把。
jdk8 之方法引用
方法引用 實際上是lamda函式的語法糖 有時候並不適用 我們可以講方法引用看做乙個函式指標.function pointer 方法引用分為4類 類名 靜態方法名 建立乙個類 public class student public void setname string name public in...
JDK8的新特性
這兩天開始看jdk8的新特性,先看了lembda表示式和stream,就乙個感覺,優雅。趕緊將這兩天的成果總結一下 lembda表示式是乙個簡潔 可傳遞的匿名函式,實現了把 塊賦值給乙個變數的功能 格式就是 parameters expression,需要注意的是 引數可以為空 引數為乙個值得時候,...
jdk8的新特性
lambda表示式 格式為 符號左邊為表示式需要的所有引數 符號右邊為表示式要執行的功能 將之前的匿名內部內作為引數傳遞直接可以使用lambda表示式完成 比如lists new arraylist new arraylist stirng public int compare string a,s...