2017-12-19 3 views
0

Ich arbeite gerade an einem Programm, wo ich durch eine Liste streame, den ersten Wert für eines der Felder erhalte und das Ergebnis speichere.Führen Sie mehrere get-Operationen mit einem Stream in Java 8 durch und speichern Sie die Ergebnisse

Das Produktobjekt hat zwei Felder (Farbe und Name).

ich sparen würde der erste gefundene Name des Produkts mit Strom wie folgt aus:

List<Product> productList = Arrays.asList(new Product("red", "potatoes"), 
    new Product("blue", "orange"), new Product("yellow", "lemon"), 
    new Product("brown", "bread"), new Product("pink", "sugar")); 

String firstProductName = 
    productList.stream().map(Product::getName).filter(Objects::nonNull).findFirst().get(); 

Um den ersten gefundenen Wert der Farbe zu speichern, würde ich einen anderen Strom verwenden:

String firstProductColor = 
    productList.stream().map(Product::getColor).filter(Objects::nonNull).findFirst().get(); 

Gibt es eine Möglichkeit, diese beiden Streams zu kombinieren, so dass ich die erste Farbe und den ersten Namen in einem Stream extrahieren und in firstProductName und firstProductColor speichern kann?

Vielen Dank für Ihre Hilfe!

+0

Gibt es Garantien für Nullbedingungen? (Nullname bedeutet Nullfarbe, etc.) Wenn nicht, dann gibt es wahrscheinlich keinen schnelleren Weg, dies mit Streams zu tun. – lucasvw

+0

@lucasvw Es gibt keine Garantie für Null-Bedingungen, also denke ich, dass eine traditionelle Schleife in diesem Fall besser ist. Vielen Dank. – pike

+0

Kein Problem. Wenn Sie meine Antwort akzeptieren könnten, die darauf hinweist, dass Ihre Frage beantwortet wurde, wäre das hilfreich. – lucasvw

Antwort

1

Sie fragen nach der Verwendung von Streams, aber ohne Garantie für bestimmte Nullbedingungen, glaube ich nicht, dass dies möglich ist, da das Ergebnis von zwei verschiedenen Elementen im Stream kommen kann.

Eine Lösung mit einem einfachen for-Schleife ist möglich:

String firstProdName = null; 
String firstProdColor = null; 
for (Product prod : productList) { 
    if (firstProdName == null) // set the product name if not set 
     firstProdName = prod.getName(); 
    if (firstProdColor == null) // set the product color if not set 
     firstProdColor = prod.getColor(); 
    if (firstProdName != null && firstProdColor != null) 
     break; // both have been found - terminate loop 
} 
0

Ja, Sie können mit dem folgenden Code:

Product product = productList.get(0); 
String firstProductName = product.getName(); 
String firstProductColor = product.getColor(); 
System.out.println(firstProductName + "/" + firstProductColor); 

Ihr Ausgang wird sein: red/potatoes

Es gibt keine Notwendigkeit, einen Strom zu erzeugen, um das erste Element aus einem List zu bekommen. Dies ist der einfachste Ansatz.

Aber wenn Sie noch einen Stream verwenden möchten, die Liste nicht in zwei Ströme devide, verwenden Sie einen einzelnen, wie folgt aus:

Product product = productList.stream().filter(Objects::nonNull).findFirst().get(); 
String firstProductName = product.getName(); 
String firstProductColor = product.getColor(); 
System.out.println(firstProductName + "/" + firstProductColor); 

Der Ausgang wird die gleiche sein, wie oben: red/potatoes

+2

Sie haben die Platzierung nicht null Bedingung verpasst. Die erste Nicht-Null-Farbe kann sich von dem ersten Nicht-Null-Produktnamen unterscheiden. Ich nehme an ... –

+0

Ja. @ BoristheSpider ist genau hier. Meine Sorge ist, dass, wenn das erste Produkt einen Nullwert für entweder den Namen oder die Farbe enthält, wir nach einem Nicht-Null-Wert von einem anderen Produkt suchen würden. In diesem Fall reicht es nicht aus, nur auf das erste Produkt zu schauen. – pike

0

Streams sind nicht für diese Art von Operationen entwickelt, sollten Sie anstelle von Strom klassische Schleife verwenden, um mehrere Werte während der Einzelquerung Sammlung zu erhalten.

2

Wenn ich verstehe zu können, sollte die erste nicht-null Produktnamen und die Produktfarbe und dass die ersten nicht-null Produktnamen in der Liste als die ersten nicht in einem anderen Ort sein könnten gut abrufen mögest Nullfarbe.

Das Problem hier ist die Art und Weise, wie die Stream-Pipeline ausgeführt wird, dh wir geben nicht jedes Element des Streams durch die erste Zwischenoperation und geben dann alle von dieser Zwischenoperation zurückgegebenen Elemente durch die nächste Zwischenoperation und so weiter bis zum Terminalbetrieb. Stattdessen wird jedes Element des Streams vertikal in der Stream-Pipeline übergeben und das erste Element, das alle Zwischenoperationen erfolgreich übergibt, wird mit dem Aufruf an findFirst().get() abgerufen.

So scheint es mir, dass es sehrunwahrscheinlich die Aufgabe in der Hand mit Strom zu erreichen und auch wenn es möglich, es wird die Stromleitungen ausgeführt wird aufgrund der Art und Weise zu kompliziert werden.

Beachten Sie auch, dass get() gerade von einem Optional Aufruf ein Missbrauch ist, und Sie sollten diese Methode nie verwenden, wenn Sie 100% sicher, es sind wird ein Wert vorhanden sein; Gründe, die später erläutert werden.

jedoch unter Verwendung eines for-Schleife oder eine foreach Schleife können wir die Daten in einem einzigen Durchlauf durch die Liste zum Beispiel durch lucaswv Antwort wie vorgeschlagen erforderlich bekommen.

Zusätzlich zu den oben genannten, möchte ich auf den Missbrauch von Optional hinweisen. wenn Sie das tun:

...findFirst().get() 

nicht anders ist es, ein Verfahren zu nennen, die null, sondern der Bewachung gegen null zurückkehren könnte, wenn die Methode ein Ergebnis zurückgibt werden Sie einfach eine andere Methode auf dem Rückgabewert dieser Methode aufrufen was zu einem NullPointerException führen könnte.

Umgekehrt würde der Aufruf an get() von einem Optional zu einem NoSuchElementException führen, wenn kein Wert vorhanden ist; Daher ist es in den meisten Fällen nicht ideal, get() direkt aus einem Optional Ergebnis zu verwenden.

Um eine solche Ausnahme zu verhindern, verwenden Sie OrElse, um den Wert zurückzugeben, falls vorhanden, andernfalls einen Standardwert anzugeben.

Offensichtlich ist Optional.get() es für einen Grund, aber es ist ein Fehler, die von den API-Designer und daher würde ich empfehlen Sie immer orElse oder orElseGet abhängig von der Situation verwenden.

Verwandte Themen