Ein mehrdimensionales Array mit einem Stream füllen

7

Ich bin neu in Java 8 und kann derzeit Streams nicht vollständig erfassen. Ist es möglich, ein Array mit den funktionalen Funktionen des Streams zu füllen? Dies ist ein Beispielcode, wie ich es mit einem Standard für die Schleife machen würde:

%Vor%

Wenn es möglich ist, wie würde ich es mit Stream tun? Wenn es möglich ist, ist es bequem (Leistung und Lesbarkeit)?

    
Angelo Alvisi 26.09.2014, 01:07
quelle

4 Antworten

12

Hier haben Sie eine Lösung, die das Array erzeugt, anstatt eine zuvor definierte Variable zu ändern:

%Vor%

Wenn Sie parallele Streams verwenden wollen, ist es sehr wichtig, Nebenwirkungen wie Modifikationen einer Variablen (Array oder Objekt) zu vermeiden. Es kann zu Race Conditions oder anderen Nebenläufigkeitsproblemen führen. Sie können mehr darüber in der Dokumentation des Pakets java.util.stream lesen - Siehe Nicht-Interferenz , Stateless-Verhalten und Nebenwirkungen Abschnitte.

    
Lukasz Wiktor 17.11.2014, 18:28
quelle
4

Der beste Weg ist eine Kombination der beiden Ansätze von Stuart Marks 'Antwort .

%Vor%

Die Argumentation, die zu der Lösung führt, besagt, dass das "Füllen eines mehrdimensionalen Arrays" in Java bedeutet: "Iterieren über die äußeren Arrays" gefolgt von "Füllen eines eindimensionalen Arrays" als String[][] ist nur a Ein Array von String[] -Elementen in Java. Um ihre Elemente zu setzen, müssen Sie über alle String[] -Elemente iterieren und da Sie den Index zur Berechnung des endgültigen Wertes benötigen, können Sie Arrays.stream(array).forEach(…) nicht verwenden. Für das äußere Array ist es also angemessen, über die Indizes zu iterieren.

Bei den inneren Arrays wird nach der besten Lösung zum Modifizieren eines (eindimensionalen) Arrays gesucht. Hier ist Arrays.setAll(…,…) geeignet.

    
Holger 26.09.2014 09:26
quelle
2

Es gibt mehrere Möglichkeiten, dies zu tun.

Ein Weg ist mit einem paar verschachtelten IntStreams über die Zeilen- und Spaltenindizes:

%Vor%

Ein anderer vielversprechender Weg ist die Verwendung von Array.setAll anstelle von Streams. Dies ist ideal zum Generieren von Werten für ein eindimensionales Array: Sie stellen eine Funktion bereit, die vom Arrayindex auf den Wert zuordnet, der im Array zugewiesen werden soll. Zum Beispiel könnten Sie dies tun:

%Vor%

Leider ist es für mehrdimensionale Arrays weniger geeignet. Die setAll -Methode, die ein Lambda akzeptiert, das einen Wert zurückgibt, der dem Array-Speicherort an diesem Index zugewiesen ist. Wenn Sie ein mehrdimensionales Array erstellt haben, werden die höheren Dimensionen bereits mit niederdimensionalen Arrays initialisiert. Sie möchten ihnen nicht zuweisen, aber Sie möchten das implizite Schleifenverhalten von setAll .

In diesem Sinne können Sie setAll verwenden, um das mehrdimensionale Array wie folgt zu initialisieren:

%Vor%

Die innere setAll ist ziemlich nett, aber die äußere muss eine Anweisung Lambda haben, die die innere setAll aufruft und dann das aktuelle Array zurückgibt. Nicht zu hübsch.

Es ist mir nicht klar, dass einer dieser Ansätze besser ist als die typischen verschachtelten for-Schleifen.

    
Stuart Marks 26.09.2014 06:19
quelle
0

Nachdem ich daran gearbeitet und getestet habe, ist die beste Option, mit der ich gekommen bin:

%Vor%

(In dem speziellen Fall, den ich vorgeschlagen habe, wäre es:

%Vor%

Für ein 3D-Array ist es einfach:

%Vor%

Dies ist der Code, mit dem das Programm die schnellste Option auswählen kann:

%Vor%

die funktionale Schnittstelle:

%Vor%     
Angelo Alvisi 18.11.2014 23:21
quelle