5

sagen, wir haben eine Customer Klasse:in flatMap während Array-Mapping

public class Customer { 
    private Car[] cars; 
    // getter, setter, constructor 
} 

und Sammlung von Kunden, die wir auf Autos kartieren müssen.

Ich tue es Zeit irgendwie so:

Collection<Customer> customers = ... 
customers.stream().flatMap(
     customer -> Arrays.stream(customer.getCars()) 
)... 

Es funktioniert gut, aber der Code sieht nicht elegant. Ich würde es wirklich gern durch Code ersetzen, der Methodenverweise verwendet, die normalerweise lesbarer und kompakter aussehen. Aber die Verwendung eines Array-Feldes macht es schwierig.

Frage: gibt es eine Möglichkeit, die flatMap Anruf zu verbessern, so dass es besser lesbar/kompakt/klar sein wird?

+6

Nun können Sie 'customers.stream(). Map (Customer :: getCars) .flatMap (Arrays :: stream)' aber IMO Ihre Lösung ist lesbar und elegant. –

Antwort

7

können Sie teilen den flatMap Anruf in zwei Anrufe - map und flatMap - jeweils eine Methode Referenz Empfang:

Collection<Customer> customers = ... 
customers.stream() 
     .map(Customer::getCars) 
     .flatMap(Arrays::stream)... 
3

Sie verwenden:

.map(Customer::getCars) 
.flatMap(Arrays::stream) 

Aber ich glaube nicht, das ist mehr elegant in irgendeiner Weise. Und das alles als Methodenreferenzen zu haben, macht es zumindest für mich weniger lesbar. Ich sollte mir erklären, warum ich das weniger lesbar finde, weil es zwei Phasen gibt, die ich jetzt verstehen muss, wenn ich diesen Code lese. Warum map ist fertig und warum flatMap ist getan - könnte jedoch gering erscheinen.

6

Fügen Sie einfach eine Methode zu Customer, die einen Stream von Car s zurückgibt. Mit typischen Namenskonventionen, es würde so aussehen

public Stream<Car> cars() { 
    return Arrays.stream(cars); 
} 

Dann können Sie es wie

customers.stream().flatMap(Customer::cars) 

Im Allgemeinen können die Eigenschaften eines wandelbaren Typ wie ein Array sollte mit Vorsicht behandelt werden. Die einzige Möglichkeit, Änderungen durch einen Getter zu verhindern, besteht darin, eine Kopie zu erstellen. So bietet ein alternatives Verfahren, das einen Nur-Lese-Typ wie einen Stream zurückgibt, der kein Kopieren benötigt, zusätzliche Verwendungen, abgesehen davon, flatMap ordentlich zu machen.

+5

Dieser Ansatz hat den zusätzlichen Vorteil, dass, wenn das Array von Autos 'null' ist, Sie auch diesen Fall in der Methode behandeln können: 'return cars == null? Stream.empty(): Arrays.stream (Autos); ' –