Die kanonische Lösung ist flatMap
zu verwenden. Der schwierige Teil besteht jedoch darin, das Objekt Key
aus den mehreren Eingangspegeln zu erstellen.
Der Straight-Forward-Ansatz ist die Auswertung in der innersten Funktion zu tun, wo jeder Wert in
Umfang ist
final List<Key> keys = firstElementCreator.getApplicableElements().stream()
.flatMap(first -> secondElementCreator.getApplicableElements().stream()
.flatMap(second -> thirdElementCreator.getApplicableElements().stream()
// ... more creators
.map(X -> new Key(first, second, third, ..., X))))
.collect(Collectors.toList());
aber das wird bald unpraktisch mit tiefer Verschachtelung
Eine Lösung ohne tiefe Verschachtelung erfordert Elemente, um Zwischenverbindungswerte zu halten. Z.B. wenn wir als Key
class Key {
String[] data;
Key(String... arg) {
data=arg;
}
public Key add(String next) {
int pos = data.length;
String[] newData=Arrays.copyOf(data, pos+1);
newData[pos]=next;
return new Key(newData);
}
@Override
public String toString() {
return "Key("+Arrays.toString(data)+')';
}
}
(unter der Annahme, String
als Elementtyp) definieren, können wir
final List<Key> keys =
firstElementCreator.getApplicableElements().stream().map(Key::new)
.flatMap(e -> secondElementCreator.getApplicableElements().stream().map(e::add))
.flatMap(e -> thirdElementCreator.getApplicableElements().stream().map(e::add))
// ... more creators
.collect(Collectors.toList());
Hinweis, dass diese flatMap
Schritte werden nun auf der gleichen Ebene verwenden, das heißt nicht mehr verschachtelt. Auch sind alle diese Schritte identisch, unterscheiden sich nur in dem tatsächlichen Erzeuger, was zu der allgemeinen Lösung führt, die eine beliebige Anzahl von Instanzen unterstützt.
List<Key> keys = Stream.of(firstElementCreator, secondElementCreator, thirdElementCreator
/* , and, some, more, if you like */)
.map(creator -> (Function<Key,Stream<Key>>)
key -> creator.getApplicableElements().stream().map(key::add))
.reduce(Stream::of, (f1,f2) -> key -> f1.apply(key).flatMap(f2))
.apply(new Key())
.collect(Collectors.toList());
hier jeder creator Zuordnung zu der identischen Strom produzierenden Funktion der bisherigen Lösung ist, dann sind alle mit einer einzigen Funktion reduzieren jede Funktion mit einem flatMap
Schritt zum nächsten der Kombination und schließlich die resultierenden Funktion wird ausgeführt, um einen Stream zu erhalten, der dann zu einer List
gesammelt wird.
Wenn Sie eine beliebige Anzahl von Schleifen benötigen, ist die Rekursion fast immer die Antwort. –