2017-02-18 10 views
12

は、私はこのストリームを持っていると言う:Javaの8つのストリーム:折りたたみ/抽象ストリーム部品

list.stream() 
    .map(fn1)  // part1 
    .map(fn2)  // 
    .filter(fn3) // 

    .flatMap(fn4) // part 2 
    .map(fn5)  // 
    .filter(fn6) // 
    .map(fn7)  // 
    .collect(Collectors.toList()) 

どのように私はそれはのように見えるようにすることができます手動でFNXパーツをほどくと、それらを一緒に入れず

list.stream() 
    .map(fnPart1)  
    .map(fnPart2) 
    .collect(Collectors.toList()) 

(メンテナンス上の理由から、私はそれらをそのままにしてfnPartXを表現したい)。

+3

Mapは、フラットマップやフィルタとは異なり、ストリーム内の項目数を変更できません。 –

+1

@BenoitParis私は疑問を誤解しているかもしれませんが、part1を 'Stream 'に、part2を 'Stream 'に割り当てて、 'Stream 'でcollectをコールすることができますか? – CKing

+3

できません。少なくとも、あなたは望むように(2つの関数を使って、最初のストリームで 'map'を使って)それをすることはできません。これは、 'map()'がストリーム*要素*(ストリーム自体ではなくストリームの各要素を変換する)上で動作するため、ストリーム自体に対する操作である要素をフィルタリングできません条件に基づくいくつかの要素)。 –

答えて

14

あなたは関数でそれを表現して構成することができます:

Function<Stream<T1>, Stream<T2>> fnPart1 = 
     s -> s.map(fn1) 
      .map(fn2) 
      .filter(fn3); 
Function<Stream<T2>, Stream<T3>> fnPart2 = 
     s -> s.flatMap(fn4) 
      .map(fn5)  
      .filter(fn6) 
      .map(fn7); 

fnPart1.andThen(fnPart2).apply(list.stream()).collect(Collectors.toList()); 

機能の入力および出力の種類はそれに応じて一致させる必要があります。

これは、次のような構築、より複雑な組成の基礎となることができます。これは、このように使用することができます

public class Composer<T>{ 
    private final T element; 

    private Composer(T element){ 
     this.element = element; 
    } 

    public <T2> Composer<T2> andThen(Function<? super T, ? extends T2> f){ 
     return new Composer<>(f.apply(element)); 
    } 

    public T get(){ 
     return element; 
    } 

    public static <T> Composer<T> of(T element){ 
     return new Composer<T>(element); 
    } 
} 

Composer.of(list.stream()) 
    .andThen(fnPart1) 
    .andThen(fnPart2) 
    .get() 
    .collect(Collectors.toList()); 
+3

'Composer'はもっと汎用的なものかもしれないので、それは単なるストリーム以上のもので使うことができます。それは私に「オプション」を思い出させる。 – 4castle

+4

@ 4castleあなたは正しいです。 Composerはストリーム固有のプロパティを使用しません。編集しました。これは、機能の構成を、OPが望んでいるものと同様の構造にするための試みです。 – Calculator

+0

ありがとうございました!まさに私が探していたもの。その間に物を具体化する必要があることを心配していましたが、それでは、関数を作成することができます。 – BenoitParis

5

あなたはflatMapをマップしない使用する必要があります。

Stream<T2> fnPart1(T1 t1) { 
    return Stream.of(fn2(fn1(t1))).filter(fn3); 
} 

Stream<T3> fnPart2(T2 t2) { 
    return fn4(t2).map(fn5).filter(fn6).map(fn7); 
} 

さらに簡素化が可能である:私はあなたのタイプは、あなたがストリーム操作の一部を削除することもできます。もちろん、

list.stream() 
    .flatMap(fnPart1)  
    .flatMap(fnPart2) 
    .collect(Collectors.toList()) 

Stream<T2> fnPart1(T1 t1) { 
    return Stream.of(t1).map(fn1).map(fn2).filter(fn3); 
} 

Stream<T3> fnPart2(T2 t2) { 
    return Stream.of(t2).flatMap(fn4).map(fn5).filter(fn6).map(fn7); 
} 

など、私はT1、T2、それらを呼ばれてきたが何であるかを知りませんfnPart1とfnPart2は単なる要素を扱っているからです。

関連する問題