2017-07-15 40 views
2

以下兩個代碼片段會產生相同的結果。Stream API中爲什麼沒有flatten()方法?

隨着flatMap

Stream.iterate(2, n -> n + 4) 
      .flatMap(n -> Stream.of(n, -(n + 2))); 

隨着map其次flatMap使用identity

Stream.iterate(2, n -> n + 4) 
      .map(n -> Stream.of(n, -(n + 2))) 
      .flatMap(Function.identity()); 

所以它似乎自然要包括在Stream接口一個無參數flatten方法(如在Scala的Stream),以允許前面的示例寫成:

Stream.iterate(2, n -> n + 4) 
      .map(n -> Stream.of(n, -(n + 2))) 
      .flatten(); 

那麼爲什麼在Stream API中沒有flatten()方法?

+3

的API已經相當臃腫。這將是一個不必要的補充。 – 4castle

+3

我認爲這個問題忽略了一點。基本的API設計說盡可能少地實現你想達到的目標。如果可能的話,flatten()方法沒有任何理由。試想一下,將所有可能的用例作爲API中的專用方法。它會很快膨脹。 – loonytune

+1

我不認爲API膨脹是一個有效的觀點。正如我在問題中提到的那樣,Scala中有'flatten'(它也有'flatMap')。我甚至可以改變論點並說,好吧,如果問題可以通過結合'map'和'flatten'來解決,爲什麼還要包含'flatMap'。當然,爲什麼'flatMap'存在的原因是性能和方便。這是簡約API和便捷API之間的折衷。 –

回答

5

A flatten方法無法在Java中實現。它只能在Stream<? extends Stream<?>>上調用,但無法確定某些類型的T extends Stream<R>是否爲R

如果你看一下方法簽名斯卡拉:

def flatten[B](implicit asTraversable: (A) ⇒ GenTraversableOnce[B]): Stream[B] 

它其實需要一個隱含的證據參數類型A是某種類型B的集合。

flatMap方法在Java中需要一個功能T -> Stream<? extends R>

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

所以我們知道,它可以被夷爲平地,Stream<R>

靜態實施flatten是可能的:

static <R> Stream<R> flatten(Stream<? extends Stream<? extends R>> stream) { 
    return stream.flatMap(Function.identity()); 
} 
相關問題