2016-04-13 14 views
0

私は入れ子になったforループを持っています。私はストリームで置き換えたいと思いますが、可能ならば方法を理解できません。私が到着することができました唯一の解決策は、基本的には代わりに、ループのforEachを使用してまったく同じに見えている Javaストリームは入れ子になったforループを置き換えます

for (Object outer : owner.getOuterList()) 
    for (Object inner : owner.getInnerList()) 
     if (cond(outer, inner)) 
      func(outer, inner); 
     else 
      moo(outer, inner); 

の下に基本的なループがあります。 flatMapが該当するようですが、両方のリストを取得する方法を理解できません。

+0

これらが純粋に必須のものであれば、それはまったく同じように見えます。ストリームは、一般的に_new_要素を変換してフィルタリングして取り出します。 –

+1

うん、@柱のリンクは基本的にあなたが必要なものです。 '内側とnewの両方を保持するためのTupleクラスを常に持っていますが、外側 '。ここでは両方とも 'Object'であるため、配列を乱用する可能性があります...まったく:' for'ループを維持してください。 – Tunaki

+0

よろしくお願いします。Pillar and Tunaki。それを書くためには、はるかにクリーンな方法ではないということがある。 – twentylemon

答えて

1

主な問題は、内部ループ本体

if (cond(outer, inner)) 
    func(outer, inner); 
else 
    moo(outer, inner); 

は、ストリームAPIには対応がなく、最もthinkableソリューションのための単一の不透明なアクションのままなので、最も簡単な解決策はConsumerとしてそれを表現することですforEachをネストして呼び出すと、既に入れられているループforのネストには何のメリットもありません。

あなたはflatMapベースのソリューションを強化したい場合は、次のことができます。それは、その人自身がこれらをキャプチャすることができる機能として[outer,inner]にマッピングするためのペア/タプル型を必要としない

owner.getOuterList().stream().flatMap(
    outer -> owner.getInnerList().stream().<Runnable>map(
     inner -> cond(outer, inner)?() -> func(outer, inner):() -> moo(outer, inner)) 
).forEach(Runnable::run); 

値。これは内部ストリーム処理の状態を評価するが、外側ストリーム処理ではfuncまたはmooのいずれかの実際の呼び出しが行われることに注意してください。外側ストリーム内のすべてを処理するように設定することができます。

owner.getOuterList().stream().flatMap(
    outer -> owner.getInnerList().stream().<Runnable>map(
     inner ->() -> { if(cond(outer,inner)) func(outer,inner); else moo(outer,inner); }) 
).forEach(Runnable::run); 

これは、元の内側ループのボディを不透明なアクションとして扱います。

私は、元のネストされたforループよりもどちらも本当の勝利ではないことは明らかです。

関連する問題