原文鏈接:https://blog.csdn.net/qq_29411737/article/details/80835658
jdk1.8新特性知識點:
-
Lambda表達式
- 注:當一個接口中存在多個抽象方法時,如果使用lambda表達式,並不能智能匹配對應的抽象方法,因此引入了函數式接口的概念
-
函數式接口
- 什么是函數式接口? 簡單來說就是只定義了一個抽象方法的接口(Object類的public方法除外),就是函數式接口,並且還提供了注解:@FunctionalInterface
-
*注意:
* 1.lambda體中調用方法的參數列表與返回值類型,要與函數式接口中抽象方法的函數列表和返回值類型保持一致!
* 2.若lambda參數列表中的第一個參數是實例方法的調用者,而第二個參數是實例方法的參數時,可以使用ClassName::method
* -
常見的四大函數式接口
- Consumer 《T》:消費型接口,有參無返回值 con.accept(str);
- Supplier 《T》:供給型接口,無參有返回值 sup.get();
- Function 《T,R》::函數式接口,有參有返回值 fun.apply(num);
- Predicate《T》: 斷言型接口,有參有返回值,返回值是boolean類型 pre.test(str);
- 在四大核心函數式接口基礎上,還提供了諸如BiFunction、BinaryOperation、toIntFunction等擴展的函數式接口,都是在這四種函數式接口上擴展而來的,不做贅述。
-
總結:函數式接口的提出是為了讓我們更加方便的使用lambda表達式,不需要自己再手動創建一個函數式接口,直接拿來用就好了
-
*方法引用和構造器調用
-
(a) 方法引用
三種表現形式:
1. 對象::實例方法名
2. 類::靜態方法名
3. 類::實例方法名 (lambda參數列表中第一個參數是實例方法的調用 者,第二個參數是實例方法的參數時可用)(b)構造器引用
格式:ClassName::new(c)數組引用
格式:Type[]::new
-
-
Stream API
-
Stream操作的三個步驟
- 創建stream
- 中間操作(過濾、map)
- 終止操作
- 較強大的兩個終止操作 reduce和collect
- reduce操作: reduce:(T identity,BinaryOperator)/reduce(BinaryOperator)-可以將流中元素反復結合起來,得到一個值;
- collect操作:Collect-將流轉換為其他形式,接收一個Collection接口的實現,用於給Stream中元素做匯總的方法
-
並行流和串行流
- 在jdk1.8新的stream包中針對集合的操作也提供了並行操作流和串行操作流。並行流就是把內容切割成多個數據塊,並且使用多個線程分別處理每個數據塊的內容。Stream api中聲明可以通過parallel()與sequential()方法在並行流和串行流之間進行切換。
jdk1.8並行流使用的是fork/join框架進行並行操作
- 在jdk1.8新的stream包中針對集合的操作也提供了並行操作流和串行操作流。並行流就是把內容切割成多個數據塊,並且使用多個線程分別處理每個數據塊的內容。Stream api中聲明可以通過parallel()與sequential()方法在並行流和串行流之間進行切換。
-
ForkJoin框架
-
Fork/Join 框架:就是在必要的情況下,將一個大任務,進行拆分(fork)成若干個小任務(拆到不可再拆時),再將一個個的小任務運算的結果進行join 匯總。
關鍵字:遞歸分合、分而治之。
采用 “工作竊取”模式(work-stealing):
當執行新的任務時它可以將其拆分分成更小的任務執行,並將小任務加到線程隊列中,然后再從一個隨機線程的隊列中偷一個並把它放在自己的隊列中相對於一般的線程池實現,fork/join框架的優勢體現在對其中包含的任務的處理方式上.在一般的線程池中,如果一個線程正在執行的任務由於某些原因無法繼續運行,那么該線程會處於等待狀態.而在fork/join框架實現中,如果某個子問題由於等待另外一個子問題的完成而無法繼續運行.那么處理該子問題的線程會主動尋找其他尚未運行的子問題來執行.這種方式減少了線程的等待時間,提高了性能.。
-
-
Optional容器
- 使用Optional容器可以快速的定位NPE,並且在一定程度上可以減少對參數非空檢驗的代碼量。
-
/**
* Optional.of(T t); // 創建一個Optional實例
* Optional.empty(); // 創建一個空的Optional實例
* Optional.ofNullable(T t); // 若T不為null,創建一個Optional實例,否則創建一個空實例
* isPresent(); // 判斷是夠包含值
* orElse(T t); //如果調用對象包含值,返回該值,否則返回T
* orElseGet(Supplier s); // 如果調用對象包含值,返回該值,否則返回s中獲取的值
* map(Function f): // 如果有值對其處理,並返回處理后的Optional,否則返回Optional.empty();
* flatMap(Function mapper);// 與map類似。返回值是Optional
*
* 總結:Optional.of(null) 會直接報NPE
*/
-
-
接口中的默認方法和靜態方法
- 在接口中可以使用default和static關鍵字來修飾接口中定義的普通方法
-
新時間日期API
- 新的日期API LocalDate | LocalTime | LocalDateTime
新的日期API都是不可變的,更使用於多線程的使用環境中
- 新的日期API的幾個優點:
-
* 之前使用的java.util.Date月份從0開始,我們一般會+1使用,很不方便,java.time.LocalDate月份和星期都改成了enum
* java.util.Date和SimpleDateFormat都不是線程安全的,而LocalDate和LocalTime和最基本的String一樣,是不變類型,不但線程安全,而且不能修改。
* java.util.Date是一個“萬能接口”,它包含日期、時間,還有毫秒數,更加明確需求取舍
* 新接口更好用的原因是考慮到了日期時間的操作,經常發生往前推或往后推幾天的情況。用java.util.Date配合Calendar要寫好多代碼,而且一般的開發人員還不一定能寫對。
-
- 新的日期API LocalDate | LocalTime | LocalDateTime
hashmap數據結構
(hashmap數據結構:在jdk1.8中對hashMap等map集合的數據結構優化。hashMap數據結構的優化 (知識點)
1 原來的hashMap采用的數據結構是哈希表(數組+鏈表),hashMap默認大小是16,一個0-15索引的數組,
2 如何往里面存儲元素: 首先調用元素的hashcode 方法,計算出哈希碼值,經過哈希算法算成數組的索引值,如果對應的索引處沒有元素,直接存放,如果有對象在,那么比較它們的equals方法比較內容 如果內容一樣,后一個value會將前一個value的值覆蓋,如果不一樣,在1.7的時候,后加的放在前面,形成一個鏈表,形成了碰撞,在某些情況下如果鏈表 無限下去,那么效率極低,碰撞是避免不了的
3 加載因子:0.75,數組擴容: 達到總容量的75%,就進行擴容,但是無法避免碰撞的情況發生 ;在1.8之后,在數組+鏈表+紅黑樹來實現hashmap,當碰撞的元素個數大於8時 & 總容量大於64,會有紅黑樹的引入 ;除了添加之后,效率都比鏈表高,1.8之后鏈表新進元素加到末尾
4 ConcurrentHashMap (鎖分段機制),concurrentLevel,jdk1.8采用CAS算法(無鎖算法,不再使用鎖分段),數組+鏈表中也引入了紅黑樹的使用
底層數據結構: ConcurrentHashMap在jdk1.7和jdk1.8中的不同
)
