Foreach Schleifen in Streams umändern

Monokuma

Aktives Mitglied
Hallo! Ich hab ein Problem bei meinem Versuch eine Foreach Schleife in einen Stream umzuwandeln.
Java:
for (PickOrder pickOrder : pickOrders) {
            for (PickOrderLine pickOrderLine : pickOrder.getPickOrderLines()) {
                if (pickOrderLine.getQuantity() > quantityOnHand.get(pickOrderLine.getProductCode())) {
                    return productCollection.findByCode(pickOrderLine.getProductCode());
                }
            }
       }
Das ist die foreach Schleife und ich hab schon einen Versuch getätigt, aber der funktioniert nicht.

Java:
pickOrders.stream()
                .flatMap(pickOrder -> pickOrder.getPickOrderLines().stream())
                .filter(pickOrderLine -> pickOrderLine.getQuantity() > quantityOnHand.get(pickOrderLine.getProductCode()))
                .collect(Collectors.toList()).stream().findFirst();

Ich würde mich sehr über Hilfe freuen. Ich hab noch andere foreach Schleifen, bei denen ich auch die Hilfe brauche, aber eins nach dem anderen.
 

httpdigest

Top Contributor
Was genau geht denn daran nicht? Sieht richtig aus. Nur, dass du halt aus dem gesamten Ausdruck ein Optional bekommst. Aber da kannst du ja mit .orElse(<wasDuZurückGibstWennKeinWertGefundenWird>) auch einfach das zurückgeben, was deine Methode nach der Schleife zurückgegeben hätte.
Und, du brauchst auch eigentlich kein collect:
Java:
return pickOrders
      .stream()
      .flatMap(po -> po.getPickOrderLines().stream())
      .filter(pol -> pol.getQuantity() > quantityOnHand.get(pol.getProductCode()))
      .findFirst()
      .orElse(null);
 

Monokuma

Aktives Mitglied
Moment. Ich glaube ich hab was vergessen zu erwähnen. Also meine ganze Methode soll dann ein Product Objekt zurückgeben

Java:
private Product getNextProduct() {
        return pickOrders
                .stream()
                .flatMap(n -> n.getPickOrderLines().stream())
                .filter(p -> p.getQuantity() > quantityOnHand.get(p.getProductCode()))
                .findFirst()
                .orElse(null);

        return null;
    }

Der Stream returned ein PickOrderLine Objekt so weit
 

httpdigest

Top Contributor
Ach natürlich, sorry. Den fehlenden findByCode() Aufruf in deiner Stream-Lösung hatte ich überlesen. So geht's:
Java:
return pickOrders
      .stream()
      .flatMap(po -> po.getPickOrderLines().stream())
      .filter(pol -> pol.getQuantity() > quantityOnHand.get(pol.getProductCode()))
      .map(pol -> productCollection.findByCode(pol.getProductCode()))
      .findFirst()
      .orElse(null);

EDIT: Oder so (mit Optional.map()):
Java:
return pickOrders
      .stream()
      .flatMap(po -> po.getPickOrderLines().stream())
      .filter(pol -> pol.getQuantity() > quantityOnHand.get(pol.getProductCode()))
      .findFirst()
      .map(pol -> productCollection.findByCode(pol.getProductCode()))
      .orElse(null);
 
Zuletzt bearbeitet:

Monokuma

Aktives Mitglied
Java:
Map<String, Integer> removedProducts = new LinkedHashMap<>(); 
for (PickOrder pickedOrder : pickedOrders) {
                for (PickOrderLine pickedOrderLines : pickedOrder.getPickOrderLines()) {
                    if (!removedProducts.containsKey(pickedOrderLines.getProductCode())) {
                        removedProducts.put(pickedOrderLines.getProductCode(), pickedOrderLines.getQuantity());
                    } else {
                        removedProducts.replace(pickedOrderLines.getProductCode(),
                                removedProducts.get(pickedOrderLines.getProductCode()) +
                                        pickedOrderLines.getQuantity());
                    }
                }
}


Ich habe jetzt diese foreach Schleife, die ich in einen Stream umwandeln will. Ich habe noch keine richtige Lösung dafür. Kann ich ein paar Tipps haben?
 

LimDul

Top Contributor
Aus dem Bauch heraus würde ich die eher so lassen - alternativ eine Variante wie folgt:

Java:
pickedorder.stream().flatMap(p->p.getPickOrderLines().stream().foreach(l->verarbeite(l, removedProducts));

Sprich den if/else Teil in eine eigene Methode auszulagern und dann aufzurufen. Direkt in einem Stream geht mit Sicherheit auch, aber wird haarig und schwer lesbar. Streams sind toll wenn jedes Element gleich behandelt wird - und das ist hier nicht mehr der Fall.
 

httpdigest

Top Contributor
Das ist sehr einfach mit einem toMap Collector umzusetzen. Die Essenz dessen, was du tust, ist ja eine Map zu bauen, bei der der Schlüssel der ProductCode ist und der Value die Quantity und bei mehreren gleichen Keys soll die Quantity summiert werden:
Java:
Map<String, Integer> removedProducts =
     pickedOrders
    .stream()
    .flatMap(po -> po.getPickOrderLines().stream())
    .collect(Collectors.toMap(
        pol -> pol.getProductCode(),
        pol -> pol.getQuantity(),
        (q1, q2) -> q1 + q2));
 

Monokuma

Aktives Mitglied
Das ist sehr einfach mit einem toMap Collector umzusetzen. Die Essenz dessen, was du tust, ist ja eine Map zu bauen, bei der der Schlüssel der ProductCode ist und der Value die Quantity und bei mehreren gleichen Keys soll die Quantity summiert werden:
Java:
Map<String, Integer> removedProducts =
     pickedOrders
    .stream()
    .flatMap(po -> po.getPickOrderLines().stream())
    .collect(Collectors.toMap(
        pol -> pol.getProductCode(),
        pol -> pol.getQuantity(),
        (q1, q2) -> q1 + q2));
Also ist das quasi schon die Lösung oder wie soll ich das verstehen?
 

httpdigest

Top Contributor
Ich hab die erste Antwort von dir genommen gehabt. Tut mir leid
Schon okay. :) Nicht böse/persönlich gemeint.
Aber dennoch verstehe ich die Aussage nicht: Du hast meine Antwort mit dem Code gequotet und dann gefragt, ob das schon die Lösung sei.
Ja ist sie.
Und als ich dich gefragt hatte, ob du es denn überhaupt schon ausprobiert hast, hast du gesagt, dass du die erste (welche erste?) Antwort (also nicht das, was du von mir gequotet hast?) genommen hast? Verwirrung.
 

Monokuma

Aktives Mitglied
Deine Antwort war vorhin eine andere. Da hat es bei mir ein Int zurückgegeben und es war komplett rot. Deswegen habe ich gefragt, weil es bei mir nicht ging.
 

httpdigest

Top Contributor
Deine Antwort war vorhin eine andere. Da hat es bei mir ein Int zurückgegeben und es war komplett rot. Deswegen habe ich gefragt, weil es bei mir nicht ging.
Ah, verstehe. :) Ja, ich nutze die 5 Minuten Zeitspanne gerne noch etwas aus, bis zu der man den Post ohne einen "wurde editiert" Hinweis bearbeiten kann. :) Vorher war der Code noch einfach ein "return" Statement, der die Map direkt zurückgegeben hat, weil ich das so gerade in einer IDE ausprobiert hatte. Dann hatte ich gemerkt, dass du es ja einfach einer lokalen Variablen zuweist und das noch geändert.
 

Monokuma

Aktives Mitglied
Java:
for (PickOrder pickOrder : pickOrders) {
                for (String productCode : removedProducts.keySet()) {
                    if (pickOrder.containsProduct(productCode)) {
                        pickOrder.calcReplenishmentsNeeded(quantityOnHand);
                        if (error) {
                            System.out.println("Recalculating: " + pickOrder);
                        }
                        break;
                    }
                }
}

Wie bearbeite ich die foreach Umwandlung, wenn ein break drinnen ist? Oder kann ich es einfach ignorieren?
 

httpdigest

Top Contributor
Das ist ein Beispiel für einen für Streams ungeeigneten Anwendungsfall. Du willst ja einfach nur etwas mit einem Element "tun" und nicht Streamelemente in etwas "anderes" konvertieren. Das würde ich so lassen. Streams sollen ja nach Möglichkeit eine funktionale Form haben, ohne Seiteneffekte. Etwas anderes wäre es, wenn calcReplenishmentsNeeded() z.B. auf einem immutable PickOrder arbeiten würde und als Ergebnis ein neues/transformierets PickOrder erzeugen würde.
 

Monokuma

Aktives Mitglied
Java:
for (Map.Entry<String, Integer> entry : removedProducts.entrySet()) {
                if (error) {
                    System.out.println("Remove " + entry.getValue() + " pieces of " + entry.getKey());
                }
                quantityOnHand.replace(entry.getKey(), quantityOnHand.get(entry.getKey()) - entry.getValue());
}

Dann hätte ich nur noch das und das wars dann mit foreach Umwandlung
 

httpdigest

Top Contributor
Könnte vielleicht das Wort "Rekursion" oder "rekursiv" im Unterricht gefallen sein? Also, statt Schleifen in Streams zu "verstecken", solltest du das vielleicht rekursiv lösen?
 
K

kneitzel

Gast
Ja, dann überleg es Dir doch einmal. Kannst Du ja erst einmal etwas generisch nachdenken: Wie könnte z.B. eine While-Schleife in einer Rekursion abgebildet werden?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Eigene forEach()-Methode funktioniert nicht. Allgemeine Java-Themen 2
D Ant foreach Allgemeine Java-Themen 0
F Foreach und for - Schleife Allgemeine Java-Themen 10
GilbertGrape foreach Schleife Allgemeine Java-Themen 12
R foreach oder nicht? Allgemeine Java-Themen 4
F KI / Machine Learning Parameter verschachtelte for Schleifen Allgemeine Java-Themen 2
F KI / Machine Learning Parameter verschachtelte for Schleifen Allgemeine Java-Themen 1
A Mehrere for-Schleifen Allgemeine Java-Themen 2
Junger_Basileus Attribute, Arrays, Schleifen Allgemeine Java-Themen 9
E Angabe wie groß Array sein soll und in for-schleifen diesen Array füllen Allgemeine Java-Themen 3
D Integer-Array variabler Größe mit Zahlen befüllen (Schleifen) Allgemeine Java-Themen 0
C Schachbrett mit while-schleifen Allgemeine Java-Themen 7
P Erste Schritte Dynamische Anzahl von verschachtelten Schleifen Allgemeine Java-Themen 5
R kann man irgendwie mit Arrays mit Eingabefenstern und Schleifen Werte abklappern? Allgemeine Java-Themen 2
R n verschachtelte Schleifen? Allgemeine Java-Themen 14
S Welcher Schleifen type für eine Berechnung Allgemeine Java-Themen 7
R Schleifen Allgemeine Java-Themen 11
L for-Schleifen Zählfehler Allgemeine Java-Themen 6
G Code nach Schleifen und Verzweigungen durchsuchen Allgemeine Java-Themen 6
S verzweigungen und schleifen Allgemeine Java-Themen 24
B BigDecimal Schleifen Allgemeine Java-Themen 9
prakdi Zeit zum Durchlauf der Schleifen unverständlich!? Allgemeine Java-Themen 3
B Auslagerung von verschachtelten Schleifen Allgemeine Java-Themen 11
T Verschachtelte Schleifen abbrechen Allgemeine Java-Themen 3
Meldanor For-Schleifen - byte statt int? Allgemeine Java-Themen 11
S Verschachtelte Schleifen Allgemeine Java-Themen 9
Z GC -> Allokation in Schleifen Allgemeine Java-Themen 25
A Fibonacci-Zahlen & kopfgesteuerte Schleifen & Strukt Allgemeine Java-Themen 8
V Vererbung und Schleifen Allgemeine Java-Themen 5
W kompliziertes Konstrukt von Schleifen/If/else. Rekursion? Allgemeine Java-Themen 22
S schleifen Allgemeine Java-Themen 3
A Schleifen in Ant? Allgemeine Java-Themen 5
G Methode mit Schleifen NullPointerException Allgemeine Java-Themen 2
L Schleife über Schleifen Allgemeine Java-Themen 4
M Verschachtelte Schleifen (unbekannte Tiefe) Allgemeine Java-Themen 3
N Code verkürzen(mit schleifen)? Allgemeine Java-Themen 10
C Effektivitaet bei for Schleifen Allgemeine Java-Themen 18
C Performance von FOR Schleifen Allgemeine Java-Themen 25
R Lohnt sich byte und short bei Schleifen? Allgemeine Java-Themen 9
P Schleifen liefern Werte nicht wie erwartet Allgemeine Java-Themen 2
8u3631984 Frage zu Java Streams min / max Allgemeine Java-Themen 17
Z Mit Java 8+ Streams Zeilen nummern zu Zeilen hinzufügen Allgemeine Java-Themen 17
F Streams als Alternative für dieses Problem ? Allgemeine Java-Themen 15
Monokuma Lesbarkeit von Streams Allgemeine Java-Themen 6
J Streams Allgemeine Java-Themen 6
LimDul Streams und Exception Allgemeine Java-Themen 8
LimDul Mittels Streams aus Strings A B C den String A, B und C machen Allgemeine Java-Themen 12
K Lesbarkeit von Streams Allgemeine Java-Themen 5
X Ermittlung eines doppelte Paars mit Streams Allgemeine Java-Themen 50
mihe7 Lesbarkeit von Streams Allgemeine Java-Themen 5
N Streams wann .filtern? Allgemeine Java-Themen 2
A Lambda und Streams verstehen Allgemeine Java-Themen 4
J IO Streams Allgemeine Java-Themen 13
M Wie funktionieren parallele Java Streams? Allgemeine Java-Themen 1
R Collections BiPredicate in Java 8 Streams Allgemeine Java-Themen 7
F Umgehen mit übergebenen Streams Allgemeine Java-Themen 3
hdi Überwachen des err-Streams? Allgemeine Java-Themen 8
N read streams umleiten Allgemeine Java-Themen 2
DEvent GZIP Streams und gzip Allgemeine Java-Themen 2
S Streams zusammenfügen Allgemeine Java-Themen 4
J Objekt in Datei speichern mittels Streams Allgemeine Java-Themen 6
F Double mit Streams aus Datei einlesen Allgemeine Java-Themen 3
C in Streams Allgemeine Java-Themen 4
M Sind Streams asynchron? Allgemeine Java-Themen 2
Saxony DOS Konsole und deren Streams Allgemeine Java-Themen 5
B Probleme mit Streams Allgemeine Java-Themen 5
T Zwei Streams verbinden Allgemeine Java-Themen 3
L Die Wahl des richtigen Streams? Allgemeine Java-Themen 3
G Video Streams mit Servlets Allgemeine Java-Themen 3
P Streams per Mail mit JavaMailAPI versenden Allgemeine Java-Themen 3
A Streams: merkwürdiges Verhalten Allgemeine Java-Themen 7
A Streams - merkwürdiges Verhalten Allgemeine Java-Themen 2
thE_29 Problem mit Streams Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben