網頁

2021/1/18

Java 8 Stream 管線操作簡介 pipeline operations

Java 8 Stream管線操作(pipeline operations)簡介。

Stream分為中間操作(intermediate operations)與終端操作(terminal operations),兩者合稱為管線操作(pipeline operations)。整個Stream管線操作從來源開始,經過零或多個中間操作,最後以終端操作結尾。

                                   Stream pipeline operations

                                          lazy-execution               eager execution
     +--------+     +--------+     +-------------------------+     +---------------------+
     |        |     |        |     |                         |     |                     |
     | Source |---->| Stream |---->| intermediate operations |---->| terminal operations |
     |        |     |        |     |                         |     |                     |
     +--------+     +--------+     +-------------------------+     +---------------------+

e.g. Collection                          e.g. filter()                 e.g. collect()
     Arrays.stream(Object[])                  map()                         forEach()
     Stream.of(Object[])                      flapMap()                     findAny()
     BufferedReader.lines()                   peek()                        findFirst()
     ...                                      sorted()                      anyMatch()
                                              distinct()                    allMatch()
                                              ...                           ...


Stream來源 (source)


Stream的來源通常為集合(Collection)或陣列(array),並利用Java 8提供的新方法來轉換為Stream物件。

Stream<String> stream1 = Arrays.asList("a", "b", "c").stream();

Stream<String> stream2 = Stream.of("a", "b", "c");

Stream<String> stream3 = Arrays.stream(new String[] {"a", "b", "c"});

Stream<String> stream4 = new BufferedReader(new FileReader(new File("hello.txt"))).lines();


中間操作 (intermediate operations)


中間操作的結果會返回新的Stream,所以能繼續更多的中間操作。中間操作是懶執行(lazy-excuting),也就是執行到中間操作時並不會真的被執行,只有到終端操作被執行時前面的中間操作才會開始執行。

常用的Stream中間操作方法包括filter()map()flatMap()peek()等。


終端操作 (terminal operations)


終端操作遍歷前面中間操作的Stream並產生結果並結束整個管線操作。產生的結果可能是一個新的集合或只是對來源發生副作用。

常用的Stream終端操作方法包括collect()forEach()findAny()peek()等。


Stream API大量使用Java 8的lambda表達式來達到函式程式設計(Functional Programming)與流式介面(Fluent Interfaces)的寫法,

一個簡單的Stream管線操作範例如下。


/** 取得年齡大於50歲的員工姓名清單並以年齡排序 */
public List<String> getOldEmployeeNameListOrderByAge(List<Employee> employeeList) {
    return employeeList.stream() // source to Stream
            .filter(employee -> employee.getAge() > 50) // intermediate operations
            .sorted(Comparator.comparing(Employee::getAge)) // intermediate operations
            .map(Employee::getName) // intermediate operations
            .collect(Collectors.toList()); // terminal operations
}



沒有留言:

張貼留言