Optional和Stream的map與flatMap


Optional的map和flatMap

Optional存在map和flatMap方法。map源碼如下

    public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }

map方法和Stream的map方法類似,都是對變量進行映射轉換。

Optional.flatMap源碼如下:

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Objects.requireNonNull(mapper.apply(value));
    }
}

從源碼看,map和flatMap均要求optional對象非空才執行mapper方法,二者均返回Optional對象。但是map會自動將計算結果封裝為Optional對象,而flatMap需要自己進行封裝。

Stream的map和flatMap

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

map方法好說,是一個很簡單的Function方法,輸入參數類型?super T,輸出參數類型為? extends R,是一種一對一的關系。將一個流映射成另外一個流。

假設需要將list的每個字符串都映射成為大寫,

List<String> list = Arrays.asList("hello world","hello world");
list.stream().map(String::toUpperCase).forEach(s -> System.out.print(s+"8 "));
//HELLO WORLD8 HELLO WORLD8 

若現在需求變了,需要將list的每個字符串按照“ ”分割,分別處理每個單詞(list共4個單詞)。這里我們仍然使用map進行測試。

list.stream().map(s -> Stream.of(s.split(" "))).map(String::toUpperCase).forEach();

該代碼存在語法錯誤,第二個map提示所需參數為Function<? super Stream , ? extend R> mapper。這說明第一個map產生了多個流(hello流和world流),這個時候就需要使用到flatMap了。jdk8對flatMap的解釋為

Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.

意思很明確,流的每個元素都會產生一個新的流。這多個流會合並為一個流,作為flatMap的返回結果。

list.stream().flatMap(s -> Stream.of(s.split(" "))).map(String::toUpperCase).forEach(s -> System.out.println(s+"9 "));
//output:HELLO9 WORLD9 HELLO9 WORLD9 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM