1、新時代的Java語言
新時代的Java是以JDK8的發布為分水嶺,從JDK8開始,Java開發進入一個新的階段,Java8 經歷9個里程碑版本,于2014年3月18日正式發布,距今已有很長一段時間了,很多企業已經逐步遷移Java8,Java8有非常重大的變化,新增了很多新的語法與特性;
一些流行框架都采用了Java8,比如Mybatis3.5.x開始全面采用JDK8,Spring5.x開始全面采用JDK8,SpringBoot2.x開始全面采用JDK8,Spring Cloud F版開始也要求JDK8;
2、Java8的一些新變化(統計)
195新的文件增加到了JDK8(目前JDK總共4240文件)
93個新類, 89新接口,13新的枚舉
2699新方法, 56新的構造函數,49新屬性
46接口被注解為@FunctionalInterface(函數式接口)
213接口默認方法
68靜態接口方法
3、Java8有哪些新特性?
1、接口默認方法
2、函數式接口
3、Lambda表達式
4、Stream流式API
5、Optional
6、新日期處理
7、......
4、Java8新特性
新特性1:接口默認方法和靜態方法
接口默認方法:
接口不僅可以聲明未實現的抽象方法,也可以聲明已經實現了的方法,而不需要實現類去實現其方法。
默認方法就像一個普通Java方法,只是方法的修飾符用default關鍵字。
接口靜態方法
接口中可以定義靜態方法,它與普通的靜態方法沒有區別。
靜態方法就像一個普通Java靜態方法,但方法的關鍵詞只能是public或者不寫。
為什么要新增該特性?
如果JDK在java8時,在List接口中新增了一個抽象方法,而我們項目寫了一個類實現了List接口,由于項目是之前采用jdk7開發的,那么當我們項目采用jdk8運行時,就會報錯,因為你沒有實現List里面新的抽象方法。
所以Java設計人員引入了接口默認方法,其目的是為了解決接口的修改與已有的實現不兼容的問題,接口默認方法可以作為庫、框架向前兼容的一種手段。
新特性2:函數式接口
只包含一個方法的接口(指抽象方法)叫函數式接口;
Java標準庫中的java.lang.Runnable, java.util.concurrent.Callable就是典型的函數式接口。
在Java 8中通過@FunctionalInterface注解,將一個接口標注為函數式接口,該接口只能包含一個方法。
@FunctionalInterface注解不是必須的,只要接口只包含一個方法,虛擬機會自動判斷該接口為函數式接口。
一般建議在接口上使用@FunctionalInterface注解進行聲明,以免他人錯誤地往接口中添加新方法,如果在你的接口中定義了第二個抽象方法的話,編譯器會報錯。
但是標記了@FunctionalInterface注解的接口可以有一個或多個默認接口方法和靜態方法,比如Java類庫中的: java.util.Comparator 。
函數式接口里允許定義java.lang.Object里的public方法(非final方法)
Java 8中類庫中許多接口都添加了@FunctionalInterface注解,比如:
java.lang.Runnable,
java.util.Comparator,
java.util.concurrent.Callable
java.util.function包下的所有接口
函數式接口是為Java 8中的lambda而設計的,lambda表達式的方法體其實就是函數接口的實現。
新特性3:Lambda表達式
Lambda 表達式是一個匿名函數,它是一個函數式接口的具體實現方式,使用Lambda語法可以用來代替Java8之前的匿名內部類,從而簡化代碼。
任意只包含一個抽象方法的接口(函數式接口),我們都可以用lambda表達式去編寫。
Lambda表達式語法結構
包含三個部分
1、一個括號內用逗號分隔的形式參數,參數是函數式接口里面方法的參數;
2、一個箭頭符號:->
3、一個方法體,可以是表達式和代碼塊,方法體是函數式接口里面方法的實現,如果Lambda的功能語句塊比較復雜,我們可以用大括號包起來,跟普通的Java方法一樣。
總體結構如下:
(parameters) -> expression ?或者 ?(parameters) -> { statements; }
1、括號里的形式參數類型可以省略,編譯器會根據上下文來推測參數的類型,你也可以顯式地指定參數類型,如果沒有形式參數,則括號里空著。
2、方法體,如果有多行功能語句用大括號括起來,如果只有一行功能語句則可以省略大括號。
3、如果Lambda方法體只有一行return語句,則如果省略了大括號,那么return可以省略;
4、如果參數列表只有一個參數,則參數列表的小括號可以省略;
新特性4:內置功能接口
Java8的內置功能接口在java.util.function包下,主要有四大核心的內置功能型接口:
謂詞(Predicate)
函數(Function)
生產者(Supplier)
消費者(Consumer)
1、謂詞:(Predicate)
謂詞是單參數的返回布爾值的函數式接口,輸入一個參數,返回true或者false。
2、函數:(Function)
Function接受一個參數,并產生一個結果。
3、生產者:(Supplier)
Suppliers產生一個給定的泛型類型的結果。與Function不同的是Suppliers不接受輸入參數。
4、消費者:(Consumer)
Consumers代表在一個單一的輸入參數上執行操作。 Consumer的操作可能會更改輸入參數的內部狀態。
新特性5:方法引用
方法引用是用來直接訪問類或者實例的已經存在的方法或者構造方法。
方法引用是lambda表達式的一種簡寫形式。
如果lambda表達式只是調用一個特定的已經存在的方法,則可以使用方法引用。
如果你覺得lambda的方法體會很長,影響代碼可讀性,則可以用方法引用來解決。
語法:
使用?:: 操作符將方法名與對象或類的名字分隔開。
新特性6:Stream API
Stream是Java 8中引入的全新API,位于java.util.stream包下,它與 java.io 包下的 InputStream 和 OutputStream 等輸入輸出流是完全不同的概念。
Java 8 中的 Stream 是對集合(Collection)功能的增強,它專注于對集合對象進行各種非常便利高效的操作。它的底層實現使用了并行化操作, 利用Java7 中引入的 Fork/Join 框架來拆分任務,加速處理過程,充分利用了現在多核處理器的優勢。
Stream分為中間操作和末端操作。
Filter
Filter 接受一個謂詞來過濾出流中所有的元素。
Sorted
Sorted 是一個返回流的自然排序的中間運算。除非你傳遞一個定制的Comparator ,元素將被以自然順序進行排序。
Map
Map是一個中間操作,可以將集合中每個元素通過給定的函數轉變為其它對象。
Match
match是一個末端操作,可以被用來檢驗某stream是否與一個特定的謂詞相匹配,返回一個布爾值結果。
Count
計數是一個末端運算,以long類型返回在stream中的元素的數目。Parallel Streams
我們知道,streams可以是順序或者并行的。
在順序streams上的操作是在一個單線程中完成的,而并行streams上的操作是在多個線程上并發完成的。
使用并行stream可以充值利用多核處理器的優勢,提升速度和性能,而所有你所需要做的僅僅是將stream() 改為 parallelStream()即可。