(JDK1.8New)Java8版本總結

Java 8 新特性

Java 8 (又稱爲 jdk 1.8) 是 Java 語言開發的一個主要版本。 Oracle 公司於 2014 年 3 月 18 日發佈 Java 8 ,它支持函數式編程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。


新特性總結

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應用。

  • Map集合的優化及併發包的拓展

更多的新特性可以參閱官網:What's New in JDK 8

在關於 Java 8 文章的實例,我們均使用 jdk 1.8 環境,你可以使用以下命令查看當前 jdk 的版本:

$ java -version
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)

Java8新增的功能中,要數lambda表達式和流API最爲重要了.這篇文章主要介紹流API的基礎,瞭解簡單的集合聚合操作,也是Java8系列的第一篇文章,(後續會有其他文章更新)話不多說,直奔主題.

什麼是流API? 它能做一些什麼?

我們應該知道(絕對知道~)API是一個程序向使用者提供的一些方法,通過這些方法就能實現某些功能.所以對於流API來說,重點是怎麼理解"流"這個概念,所謂的流:就是數據的渠道,所以,流代表的是一個對象的序列.它和Java I/O類裏使用的"流"不同.雖然在概念上與java.util.stream中定義的流是類似的,但它們是不同的.流API中的流是描述某個流類型的對象.

流API中的流操作的數據源,是數組或者是集合.它本身是不存儲數據的,只是移動數據,在移動過程中可能會對數據進行過濾,排序或者其它操作.但是,一般情況下(絕大數情況下),流操作本身不會修改數據源.比如,對流排序不會修改數據源的順序.相反,它會創建一個新的流,其中包含排序後的結果.

從一個簡單的例子,體驗流API的強大與優雅

這個簡單的Demo,主要是對一個由1-6亂序組成的List對應的流進行操作,然後通過這個流,就可以獲取到列表裏面最大最小值,排序,過濾某些元素等等的操作.並且這此操作不會改變原List裏面的數據.Demo裏面需要注意的地方就是流API裏面的"終端操作"和"中間操作"的區別:其實也很簡單,終端操作會消費流,一個被消費過的流是不能被再次利用的,但我們在實際應用的時候,並不會受到太大的影響(Ps:如果你們能動手實踐一下我相信你體驗更好,強烈推薦!)

public class Main {

    
public static void main(String[] args) {
        learnStream();
 }

private static void learnStream() {
        
//首先,創建一個1-6亂序的List
        
List<Integer> lists = new
 
ArrayList<>();
        lists.add(4);
        lists.add(3);
        lists.add(6);
        lists.add(1);
        lists.add(5);
        lists.add(2);

        
//看看List裏面的數據是什麼樣子的先
        
System.out.print("List裏面的數據:");
        
for (Integer elem : lists) {
System.out.print(elem + " ");
// 4 3 6 1 5 2
}
        
System.out.println();

        
//最小值
        
System.out.print("List中最小的值爲:");
        
Stream<Integer> stream = lists.stream();
        
Optional<Integer> min = stream.min(Integer::compareTo);
        
if(min.isPresent()) {         
    System.out.println(min.get());
//1
}


        
//最大值
        
System.out.print("List中最大的值爲:");
lists.stream().max(Integer::compareTo).ifPresent(
    System.out::println);
//6

        
//排序
        
System.out.print("將List流進行排序:");
        
Stream<Integer> sorted = lists.stream().sorted();
        
sorted.forEach(elem -> System.out.print(elem + " "));
// 1 2 3 4 5 6

        
System.out.println();

        
//過濾
System.out.print("過濾List流,只剩下那些大於3的元素:");
lists.stream()
            .filter(elem -> elem > 3)
            .forEach(elem -> System.out.print(elem + " "));
// 4 5 6

        
System.out.println();

        
//過濾
        
System.out.println("過濾List流,只剩下那些大於0並且小於4的元素:\n=====begin=====");
        
lists.stream()
               .filter(elem -> elem > 0)
               .filter(elem -> elem < 4)
               .sorted(Integer::compareTo)
               .forEach(System.out::println);
// 1 2 3

        
System.out.println("=====end=====");
        
//經過了前面的這麼多流操作,我們再來看看List裏面的值有沒有發生什麼改變
        
System.out.print("原List裏面的數據:");
        
for (Integer elem : lists){
 System.out.print(elem + " ");
// 4 3 6 1 5 2
    
}  

如果剛纔的Demo你認真讀了,我相信你心裏面多多少少都會產生一點點漣漪.沒錯,流API結合lambda表達式,就是這麼優美!下面我詳細介紹一下整個Demo,讓大家更加清淅:

最小值

 
//最小值
System.out.print("List中最小的值爲:");
Stream<Integer> stream = lists.stream();
Optional<Integer> min = stream.min(Integer::compareTo);
if(min.isPresent()) {
    System.out.println(min.get());//1
}

首先通過stream()方法獲取List對應的流,如果你對Java8的集合框架有一定的瞭解,你應該知道stream()是由Collection接口提供的.然後就可以通過min()獲取流中的最小值了,當然這個流中的最小值肯定也是List裏面的最小值.

min()方法接收一個Comparator類型的參數,這個比較器是用於比較流中的兩個元素的.我們這裏把Integer的compareTo()的引用傳遞給了min().它返回的類型是Optional,Optional可謂是NullPointException的大殺器啊,感興趣的同學,瞭解一下.然後判斷最小值存不存在,如果存在,就通過Optional的get()讀取出來.很簡單有木有!

最大值

//最大值
System.out.print("List中最大的值爲:");
lists.stream().max(Integer::compareTo).ifPresent(System.out::println);
//6

語法糖爽YY有木有,不過需要注意的一點,因爲min()是一個終端操作,所以這個流是不可以再用了,因此我們需要通過stream()重新生成一個流,(但這其實並不影響我們的實際生產的:①方法功能單一原則②還有其它很多很強大的方法組合能讓你實現各種功能啊.)ifPresent其實和上面的最小值的if判斷是一定要,如果存在最大值,我們就打印一下,這裏只不過用了一些函數式寫法而已.

排序和遍歷

 
//排序
System.out.print("將List流進行排序:");
Stream<Integer> sorted = lists.stream().sorted();
sorted.forEach(elem -> 
System.out.print(elem + " "));
// 1 2 3 4 5 6

通過上面的講解,相信這個已經難不了你了,sorted()方法是用於排序的,它的一個重載方法可以接收一個Comparator類型的參數,讓你自定義你的排序規則.forEach方法就遍歷.

過濾

filter()是基於一個謂詞過濾流,它返回一個只包含滿足謂詞的元素的新流.它的參數形式是Predicate,是在java.util.function包下的泛型函數式接口.並且filter是一箇中間操作,而且還可以同時存在多個filter.這裏的兩個過濾器,我們都傳遞了lambda表達式.

小結一下

其實基本的流API使用就是這麼簡單,結合lambda表達式後,一切都變得特別清淅.這個簡單的Demo展示了一些基礎的功能,它或許就擴展了你操作數組或者集合框架的思路,讓你操作集合和數組,變得更加的容易,簡單和高效.

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