Java8中有兩大最爲重要的改變。第一個是 Lambda 表達式;另外一個則是 Stream API。
先說說我自己的感受:Stream API其實也是語法糖,它簡化了Java語言中對集合數據進行操作的複雜度。我自己對於這個JDK1.8的新的API只是要求能看懂就行了,別到時候看到相關代碼一臉懵逼就行。。。要我經常寫應該不太可能。。。
Stream 是 Java8 中處理集合的關鍵抽象概念,它可以指定你希望對集合進 行的操作,可以執行非常複雜的查找、過濾和映射數據等操作。 使用 Stream API 對集合數據進行操作,就類似於使用 SQL 執行的數據庫查詢。 也可以使用 Stream API 來並行執行操作。簡言之,Stream API 提供了一種高效且易於使用的處理數據的方式。
爲什麼要使用Stream API
- 實際開發中,項目中多數數據源都來自於Mysql,Oracle等。但現在數 據源可以更多了,有MongDB,Radis等,而這些NoSQL的數據就需要 Java層面去處理。
- Stream 和 Collection 集合的區別:Collection 是一種靜態的內存數據 結構,而 Stream 是有關計算的。前者是主要面向內存,存儲在內存中, 後者主要是面向 CPU,通過 CPU 實現計算。
Stream是數據渠道,用於操作數據源(集合、數組等)所生成的元素序列。 Stream 自己不會存儲元素。Stream 不會改變源對象。相反,他們會返回一個持有結果的新Stream。Stream 操作是延遲執行的。這意味着他們會等到需要結果的時候才執行。
Stream 的操作三個步驟
1- 創建 Stream:一個數據源(如:集合、數組),獲取一個流
2- 中間操作:一箇中間操作鏈,對數據源的數據進行處理
3- 終止操作(終端操作):一旦執行終止操作,就執行中間操作鏈,併產生結果。之後,不會再被使用。
創建 Stream方式
- 通過集合:Java8 中的 Collection 接口被擴展,提供了兩個獲取流 的方法: default Stream<E> stream() : 返回一個順序流 ,default Stream<E> parallelStream() : 返回一個並行流。
- 通過數組:Java8 中的 Arrays 的靜態方法 stream() 可以獲取數組流:static <T> Stream<T> stream(T[] array): 返回一個流
- 通過Stream的of():可以調用Stream類靜態方法 of(), 通過顯示值創建一個 流。它可以接收任意數量的參數。 public static<T> Stream<T> of(T... values) : 返回一個流。
- 創建無限流:可以使用靜態方法 Stream.iterate() 和 Stream.generate(), 創建無限流。
Stream 的中間操作
多箇中間操作可以連接起來形成一個流水線,除非流水線上觸發終止 操作,否則中間操作不會執行任何的處理!而在終止操作時一次性全 部處理,稱爲“惰性求值”。
Stream 的終止操作
- 終端操作會從流的流水線生成結果。其結果可以是任何不是流的值,例 如:List、Integer,甚至是 void 。
- 流進行了終止操作後,不能再次使用。
使用例子:
//篩選與切片
public void test1(){
List<Employee> list = EmployeeData.getEmployees();
// filter(Predicate p)——接收 Lambda , 從流中排除某些元素。
Stream<Employee> stream = list.stream();
//練習:查詢員工表中薪資大於7000的員工信息
stream.filter(e -> e.getSalary() > 7000).forEach(System.out::println);
System.out.println();
// limit(n)——截斷流,使其元素不超過給定數量。
list.stream().limit(3).forEach(System.out::println);
System.out.println();
// skip(n) —— 跳過元素,返回一個扔掉了前 n 個元素的流。若流中元素不足 n 個,則返回一個空流。與 limit(n) 互補
list.stream().skip(3).forEach(System.out::println);
System.out.println();
// distinct()——篩選,通過流所生成元素的 hashCode() 和 equals() 去除重複元素
list.add(new Employee(1010,"XXX",40,8000));
list.add(new Employee(1010,"XXX",41,8000));
list.add(new Employee(1010,"XXX",40,8000));
list.add(new Employee(1010,"XXX",40,8000));
list.add(new Employee(1010,"XXX",40,8000));
// System.out.println(list);
list.stream().distinct().forEach(System.out::println);
}