Java8新特性整理--簡潔實用版

Java8 新增了非常多的特性,我們主要討論以下幾個:

  • Lambda 表達式 − Lambda允許把函數作爲一個方法的參數(函數作爲參數傳遞進方法中。
  • 方法引用 − 方法引用提供了非常有用的語法,可以直接引用已有Java類或對象(實例)的方法或構造器。與lambda聯合使用,方法引用可以使語言的構造更緊湊簡潔,減少冗餘代碼。
  • 默認方法 − 默認方法就是一個在接口裏面有了一個實現的方法。
  • 新工具 − 新的編譯工具,如:Nashorn引擎 jjs、 類依賴分析器jdeps。
  • Stream API −新添加的Stream API(java.util.stream) 把真正的函數式編程風格引入到Java中。
  • Date Time API − 加強對日期與時間的處理。
  • Optional 類 − Optional 類已經成爲 Java 8 類庫的一部分,用來解決空指針異常。
  • Nashorn, JavaScript 引擎 − Java 8提供了一個新的Nashorn javascript引擎,它允許我們在JVM上運行特定的javascript應用。

1. Lambda 表達式實例

1.1. Lambda 表達式的簡單例子:

// 1. 不需要參數,返回值爲 5  
() -> 5  
  
// 2. 接收一個參數(數字類型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2個參數(數字),並返回他們的差值  
(x, y) -> x – y  
  
// 4. 接收2個int型整數,返回他們的和  
(int x, int y) -> x + y  
  
// 5. 接受一個 string 對象,並在控制檯打印,不返回任何值(看起來像是返回void)  
(String s) -> System.out.print(s)

1.2.使用注意事項

  • lambda 表達式只能引用標記了 final 的外層局部變量,這就是說不能在 lambda 內部修改定義在域外的局部變量,否則會編譯錯誤。
  • 在 Lambda 表達式當中不允許聲明一個與局部變量同名的參數或者局部變量。

 

2. 方法引用

方法引用通過方法的名字來指向一個方法。

方法引用可以使語言的構造更緊湊簡潔,減少冗餘代碼。

方法引用使用一對冒號 :: 。

names.forEach(System.out::println);

 

3. 函數式接口

函數式接口(Functional Interface)就是一個有且僅有一個抽象方法,但是可以有多個非抽象方法的接口。

函數式接口可以被隱式轉換爲 lambda 表達式。

Lambda 表達式和方法引用(實際上也可認爲是Lambda表達式)上。

JDK 1.8 新增加的函數接口:

  • java.util.function

java.util.function 它包含了很多類,用來支持 Java的 函數式編程。

 

4. 默認方法

簡單說,默認方法就是接口可以有實現方法,而且不需要實現類去實現其方法。

我們只需在方法名前面加個 default 關鍵字即可實現默認方法。

 

5. Stream

Stream 使用一種類似用 SQL 語句從數據庫查詢數據的直觀方式來提供一種對 Java 集合運算和表達的高階抽象。

這種風格將要處理的元素集合看作一種流, 流在管道中傳輸, 並且可以在管道的節點上進行處理, 比如篩選, 排序,聚合等。

元素流在管道中經過中間操作(intermediate operation)的處理,最後由最終操作(terminal operation)得到前面處理的結果。

Stream(流)是一個來自數據源的元素隊列並支持聚合操作。

5.1. Stream操作還有兩個基礎的特徵:

  • Pipelining: 中間操作都會返回流對象本身。 這樣多個操作可以串聯成一個管道, 如同流式風格(fluent style)。 這樣做可以對操作進行優化, 比如延遲執行(laziness)和短路( short-circuiting)。
  • 內部迭代: 以前對集合遍歷都是通過Iterator或者For-Each的方式, 顯式的在集合外部進行迭代, 這叫做外部迭代。 Stream提供了內部迭代的方式, 通過訪問者模式(Visitor)實現。

5.2. 在 Java 8 中, 集合接口有兩個方法來生成流:

  • stream() − 爲集合創建串行流。
  • parallelStream() − 爲集合創建並行流。
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
//parallelStream 是流並行處理程序的代替方法。以下我們使用 parallelStream 來輸出空字符串的數量:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 獲取空字符串的數量 int count = strings.parallelStream().filter(string -> string.isEmpty()).count();

5.3. 聚合操作 

5.3.1. forEach

Stream 提供了新的方法 'forEach' 來迭代流中的每個數據。以下代碼使用 forEach 輸出了10個隨機數:

Random random = new Random(); random.ints().limit(10).forEach(System.out::println);

5.3.2. map

map 方法用於映射每個元素到對應的結果,以下代碼片段使用 map 輸出了元素對應的平方數:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); // 獲取對應的平方數 List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

5.3.3. filter

filter 方法用於通過設置的條件過濾出元素。以下代碼片段使用 filter 方法過濾出空字符串:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 獲取空字符串的數量 int count = strings.stream().filter(string -> string.isEmpty()).count();

5.3.4. limit

limit 方法用於獲取指定數量的流。 以下代碼片段使用 limit 方法打印出 10 條數據:

Random random = new Random(); 
random.ints().limit(10).forEach(System.out::println);

5.3.5. sorted

sorted 方法用於對流進行排序。以下代碼片段使用 sorted 方法對輸出的 10 個隨機數進行排序:

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);

5.3.6. Collectors

Collectors 類實現很多歸約操作,如將流轉換成集合和聚合元素。Collectors 可用於返回列表或字符串:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); 
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); 
System.out.println("篩選列表: " + filtered); 
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", ")); 
System.out.println("合併字符串: " + mergedString);

 

6. Optional 類

Optional 類是一個可以爲null的容器對象。如果值存在則isPresent()方法會返回true,調用get()方法會返回該對象。

Optional 是個容器:它可以保存類型T的值,或者僅僅保存null。Optional提供很多有用的方法,這樣我們就不用顯式進行空值檢測。

Optional 類的引入很好的解決空指針異常。

 

7.日期時間 API

Java 8 在 java.time 包下提供了很多新的 API。以下爲兩個比較重要的 API:

  • Local(本地) − 簡化了日期時間的處理,沒有時區的問題。
  • Zoned(時區) − 通過制定的時區處理日期時間。

新的java.time包涵蓋了所有處理日期,時間,日期/時間,時區,時刻(instants),過程(during)與時鐘(clock)的操作。

 

8. Base64

Java 8 內置了 Base64 編碼的編碼器和解碼器。

Base64工具類提供了一套靜態方法獲取下面三種BASE64編解碼器:

  • 基本:輸出被映射到一組字符A-Za-z0-9+/,編碼不添加任何行標,輸出的解碼僅支持A-Za-z0-9+/。
  • URL:輸出映射到一組字符A-Za-z0-9+_,輸出是URL和文件。
  • MIME:輸出隱射到MIME友好格式。輸出每行不超過76字符,並且使用'\r'並跟隨'\n'作爲分割。編碼輸出最後沒有行分割。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章