2016-04-13 7 views
0

Ich habe eine verschachtelte For-Schleife, die ich gerne durch Streams ersetzen würde, aber ich kann nicht herausfinden, wie, wenn es möglich ist. Die Grundschleife ist unterJava-Streams ersetzen verschachtelt für Schleife

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

Die einzige Lösung, die ich im Stande gewesen bin zu kommen ist sieht im Grunde genau die gleichen die forEach anstelle der Schleifen verwenden. flatMap scheint anwendbar, aber ich kann nicht herausfinden, wie man beide Listen bekommt.

+0

Wenn das rein zwingende Dinge sind, dann wird es genau so aussehen. Streams dienen dazu, im Allgemeinen _new_ Elemente zu transformieren und zu filtern und herauszuholen. –

+1

Ja, @Pillar Link ist im Grunde, was Sie brauchen. '.flatMap (äußere -> owner.getInnerList(). stream(). map (innere -> neue Objekt [] {äußere, innere}))' Das Problem ist immer mit einer Tuple-Klasse für das Halten von 'inneren' und ' äußerlich. Da sie beide "Objekt" sind, könnten wir ein Array missbrauchen ... Alles in allem: behalte die "for" -Schleife. – Tunaki

+0

Ok, danke Pillar und Tunaki. Irgendwie nervt es, dass es keinen wesentlich saubereren Weg gibt, es zu schreiben. – twentylemon

Antwort

1

Das Hauptproblem ist, dass der innere Schleifenkörper

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

kein Gegenstück in dem Stream-API hat und bleibt eine einzelne undurchsichtige Aktion für die meisten denkbaren Lösungen, so dass die einfachste Lösung ist es als Consumer auszudrücken, die Sie rufen einen verschachtelten forEach auf, der der verschachtelten for-Schleife, die Sie bereits haben, keinen Vorteil bietet.

Wenn Sie eine flatMap basierte Lösung erzwingen möchten, können Sie wie folgt vorgehen:

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

Es ist nicht ein Paar/Tuple Typ für die Zuordnung zu [outer,inner] wie die Funktionen benötigt für sich alleine fähig, diese einzufangen Werte. Beachten Sie, dass dies die Bedingung in der Verarbeitung des inneren Datenstroms auswertet, der tatsächliche Aufruf von func oder moo jedoch in der Verarbeitung des äußeren Datenstroms erfolgt. Sie können die Verarbeitung alles innerhalb des äußeren Stromes erzwingen mit

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); 

, die, wie gesagt, Ihrer ursprünglichen inneren Schleife Körper wie eine undurchsichtige Aktion behandelt.

Ich denke, es ist klar, dass weder ein echter Gewinn über die ursprüngliche verschachtelte for Schleife hier ist.

Verwandte Themen