基本上很多面試者會被問到了,你瞭解一下JDK 1.8的新特性請說說看,這個時候才意識到它的重要,其實好多已經用在了項目中,在這裏給大家總結一下。
1.速度更快
1.1 優化了HashMap以及ConcurrentHashMap
在1.8之後,在數組+鏈表+紅黑樹來實現hashmap,當碰撞的元素個數大於8時並且總容量大於64,會有紅黑樹的引入。除了添加之後,效率都比鏈表高,1.8之後鏈表新進元素加到末尾 ConcurrentHashMap (鎖分段機制),1.8採用CAS算法(無鎖算法,不再使用鎖分段),數組+鏈表中也引入了紅黑樹的使用。
CAS(Compare-And-Swap) 算法保證數據變量的原子性,是硬件對於併發操作的支持,這個會在後面的文章中詳細講解。
1.2 內存
JDK1.8以前內存分爲棧、堆、方法區。JDK1.8之後,方法區變成了MetaSpace元空間(採用的物理內存),元空間屬於本地內存,所以元空間的大小僅受本地內存限制,但是可以通過-XX:MaxMetaspaceSize進行增長上限的最大值設置,默認值爲4G,元空間的初始空間大小可以通過-XX:MetaspaceSize進行設置。
2.代碼更少
2.1 新增語法lambda表達式
Lambda是一個匿名函數,我們可以把 Lambda表達式理解爲是 一段可以傳遞的代碼(將代碼像數據一樣進行傳遞)。可以寫出更簡潔、更靈活的代碼。作爲一種更緊湊的代碼風格,使Java的語言表達能力得到了提升 。
2.2 Lambda的語法元素和操作符
Consumer<String> fun=(args)->System.out.println(args);
操作符(—>)左側:指定了Lambda表達式需要的所有參數。
操作符(—>)右側:指定了Lambda體,即Lambda 表達式要執行的功能。
2.3 函數式接口
消費型接口 | Consumer<T> 有參數無返回 | 對類型爲T的對象應用操作,包含方法:void accept(T t) |
供給型接口 | Supplier<T> 有參數有返回T | 返回類型爲T的對象,包含方法:T get() |
函數型接口 | Function<T, R> 有參數有返回R | 對類型爲T的對象應用操作,並返回結果。結果是R類型的對象。包含方法:R apply(T t) |
斷定型接口 | Predicate<T> 有參數有返回boolean | 確定類型爲T的對象是否滿足某約束,並返回boolean 值。包含方法boolean test(T t) |
2.4 方法&構造器&數組引用
與函數式接口相結合,自動與函數式接口中方法兼容。可以把構造器引用賦值給定義的方法,與構造器參數列表要與接口中抽象方法的參數列表一致。格式爲:
- 方法引用 ClassName::methodName
- 構造器ClassName::new
- 數組引用type[]::new
比如數組引用:
Function<Integer,Integer[]> fun = (n) -> new Integer[n];//原生方式實現
Function<Integer,Integer[]> fun = Integer[]::new;//數組引用方法實現
3.強大的Stream API
Stream是Java8中處理集合的關鍵抽象概念,它可以指定你希望對集合進行的操作,可以執行非常複雜的查找、過濾和映射數據等操作。使用StreamAPI對集合數據進行操作,就類似於使用SQL執行的數據庫查詢。
3.1 創建流
一個數據源(如:集合、數組),獲取一個流
3.2 中間操作
一箇中間操作鏈,對數據源的數據進行處理
3.2.1 篩選與切片
filter(Predicate p) | 接收Lambda從流中排除某些元素。 |
distinct() | 篩選,通過流所生成元素的 hashCode() 和 equals() 去除重複元素 |
limit(long maxSize) | 截斷流,使其元素不超過給定數量。 |
skip(long n) | 跳過元素,返回一個扔掉了前 n 個元素的流。若流中元素不足 n 個,則返回一個空流。與 limit(n) 互補 |
3.2.2 映射
map(Function f) | 接收一個函數作爲參數,該函數會被應用到每個元素上,並將其映射成一個新的元素。 |
mapToDouble(ToDoubleFunction f) | 接收一個函數作爲參數,該函數會被應用到每個元素上,產生一個新的 DoubleStream。 |
flatMap(Function f) | 接收一個函數作爲參數,將流中的每個值都換成另一個流,然後把所有流連接成一個流。 |
3.2.3 排序
sorted() | 產生一個新流,其中按自然順序排序。 |
sorted(Comparator comp) | 產生一個新流,其中按比較器順序排序。 |
3.2.4 查找與匹配
allMatch(Predicate p) | 檢查是否匹配所有元素 |
anyMatch(Predicate p) | 檢查是否至少匹配一個元素 |
noneMatch(Predicate p) | 檢查是否沒有匹配所有元素 |
findFirst() | 返回第一個元素 |
findAny() | 返回當前流中的任意元素 |
count() | 返回流中元素總數 |
max(Comparator c) | 返回流中的最大值 |
min(Comparator c) | 返回流中的最小值 |
forEach(Consumer c c) | 內部迭代( (使用Collection接口需要用戶去做迭代,稱爲外部迭代。相反,Stream API使用內部迭代) |
3.2.5 歸約
reduce(T iden, BinaryOperator b) | 可以將流中元素反覆結合起來,得到一個值。返回 T |
reduce(BinaryOperator b) | 可以將流中元素反覆結合起來,得到一個值。返回 Optional<T> |
備註:map 和 reduce 的連接通常稱爲 map-reduce 模式,因 Google 用它來進行網絡搜索而出名
3.2.6 收集
collect(Collector c) | 將流轉換爲其他形式。接收一個 Collector接口的實現,用於給Stream中元素做彙總的方法 |
3.3 終止操作
一個終止操作,執行中間操作鏈,併產生結果
4.便於並行
並行流就是把一個內容分成多個數據塊,並用不同的線程分別處理每個數據塊的流。Stream API 可以聲明性地通過 parallel() 與sequential() 在並行流與順序流之間進行切換。
Fork/Join框架是Java 7提供的一個用於並行執行任務的框架,是一個把大任務分割成若干個小任務,最終彙總每個小任務結果後得到大任務結果的框架。
5.最大化減少空指針異常
Optional<T> 類(java.util.Optional) 是一個容器類,代表一個值存在或不存在,原來用 null 表示一個值不存在,現在 Optional 可以更好的表達這個概念。並且可以避免空指針異常。常用方法如下:
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 |
6.新時間日期API
使用LocalDate 、LocalTime 、LocalDateTime分別表示使用 ISO-8601日曆系統的日期、時間、日期和時間。
Duration用於計算兩個時間間隔,Period用於計算兩個日期間隔。
7.接口中的默認方法與靜態方法
7.1 Java8中允許接口中包含具有具體實現的方法
該方法稱爲默認方法,默認方法使用 default 關鍵字修飾。
7.2 Java8中接口中允許添加靜態方法
7.3 接口默認方法的類優先原則
若一個接口中定義了一個默認方法,而另外一個父類或接口中又定義了一個同名的方法時選擇父類中的方法。如果一個父類提供了具體的實現,那麼接口中具有相同名稱和參數的默認方法會被忽略。接口衝突。如果一個父接口提供一個默認方法,而另一個接口也提供了一個具有相同名稱和參數列表的方法(不管方法是否是默認方法),那麼必須覆蓋該方法來解決衝突。
--------------如果大家喜歡我的博客,可以點擊左上角的關注哦。