2017-07-15 7 views
2

次の2つのコードスニペットで同じ結果が得られます。 flatMapStream APIにflatten()メソッドがないのはなぜですか?

identityを使用して flatMap続い map
Stream.iterate(2, n -> n + 4) 
      .flatMap(n -> Stream.of(n, -(n + 2))); 

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

だから、(Scalaの中のようなStreamインターフェースで引数なしのflatten方法が含まれるように、自然と思われます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と便利な機能のトレードオフです。 –

答えて

5

flattenメソッドをJavaで実装できませんでした。 Stream<? extends Stream<?>>でのみ呼び出し可能ですが、Rの場合はT extends Stream<R>かどうかを判断する方法はありません。

あなたはScalaではメソッドのシグネチャを見れば:

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

それは実際にタイプAは、いくつかのタイプBの集まりである暗黙の証拠パラメータを取ります。

JavaでflatMap方法が機能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()); 
} 
関連する問題