2016-05-16 8 views
1

Nehmen wir an, wir hatten zwei ArrayLists für zwei Objekte, die beide mit Dingen gefüllt waren. Zum leichteren Verständnis ist eine ArrayListe von Nummernschildern und die andere von Autos.Anruf für eine Karte sammeln?

Alle Fahrzeuge erhalten eine gültige Kfz-Kennzeichen zugewiesen und dann wird das Auto die Nummer der Platte ...

cars.addAll(plates.stream().filter(plate -> plate.getStatus() == PLATE_GOOD) 
    .map(plate -> new Car(plate.getNumber(), modelT())).collect(Collectors.toList())); 

Aber dann die Besitzer der Autos benötigt, um ihre Platten und Autos in eine Karte von Platten registrieren und Autos.

Aber die DMV verlangte, dass es keine Schleifen gibt und dass die Eigentümer einen Sammelruf verwenden würden.

TL; DR Sammeln Anruf mit mehreren Prädikaten, um eine Karte von Objekten zu füllen?

+1

Verwenden Sie 'Collectors.toMap (...)'. – Andreas

+0

@Andreas Sicher, aber das korrigiert mein Verständnis von mehreren Parametern in diesem Fall nicht. Aber danke für Ihre Zeit und ich bin froh zu wissen, dass es eine loop-lose Lösung für dieses persönliche Dilemma gibt, vorausgesetzt, dass Ihr Kommentar dies impliziert. –

Antwort

1

Sie können nicht bekommen, was Sie mit der Aussage wollen Sie bereits verwenden, da es eine Liste von Car produziert, aber es gibt keine Verbindung zwischen den Car und den Plate. Beide haben eine Plattennummer, aber das erlaubt Ihnen nicht, die Plate herauszufinden, wenn Sie eine Car haben, oder umgekehrt, ohne durch die Art von Doppelschleife zu gehen, die Sie gepostet haben - oder ohne eine Map Karte einzurichten eine Plattennummer auf einen Teller oder ein Auto. Aber wenn Sie eine Map<Plate, Car> benötigen, sollten Sie keine Map<String, Plate> oder Map<String, Car> [vorausgesetzt, die Plattennummer ist eine Zeichenfolge] einrichten, obwohl diese Karte eine nützliche Sache sein könnte, sowieso zu haben.

Ich würde vorschlagen, die Map<Plate, Car> zuerst erstellen:

Map<Plate, Car> carMap = plates.stream().filter(plate -> plate.getStatus() == PLATE_GOOD) 
.collect(Collectors.toMap(Function.identity(), plate -> new Car(plate.getNumber(), modelT()))); 

Dieses neue Car für jede Platte schaffen und die Karte einrichten. Collectors.toMap() benötigt zwei Parameter, die Funktionen sind, die auf einem Plate arbeiten. Der erste wird der Schlüssel der Karte und der zweite wird der Wert sein. Function.identity() bedeutet nur, dass wir die Plate selbst als Schlüssel verwenden. Oder Sie könnten äquivalent plate -> plate verwenden.

Um eine Liste der Autos zu erhalten, verwenden Sie carMap.values(). Dies gibt eine Collection (nicht unbedingt eine List) zurück, aber Sie können es zu einer Liste mit addAll hinzufügen. Dies wird nicht notwendigerweise die Autos in der gleichen Reihenfolge wie die Platten zurückgeben. Wenn Sie sie in der gleichen Reihenfolge benötigen, können Sie dies tun, nachdem carMap erstellen:

List<Car> carList = plates.stream().filter(plate -> plate.getStatus() == PLATE_GOOD) 
.map(plate -> carMap.get(plate)).collect(Collectors.toList())); 

Ich weiß nicht, von einer Art und Weise beide auf einmal zu tun (das Auto zu einer Liste hinzuzufügen, und fügen Sie die Platte/Auto auf eine Karte), mit Ausnahme von Ihrem eigenen Code zu schreiben, um die Liste und der Karte, um hinzuzufügen:

plates.stream().filter(plate -> plate.getStatus() == PLATE_GOOD) 
.forEachOrdered(plate -> { 
    Car car = new Car(plate.getNumber(), modelT()); 
    carList.add(car); 
    carMap.put(plate, car); }); 

forEachOrdered benötigt wird, um die Vorgänge zu gewährleisten, werden in der richtigen Reihenfolge durchgeführt. Hinweis: Ich habe dieses letzte nicht getestet. I denke, wird es ohne Synchronisierung funktionieren, aber ich bin mir nicht sicher.

+0

plates.stream(). Filter (Platte -> plate.getStatus() == PLATE_GOOD) .forEachOrdered (Platte -> { Auto = neues Auto (plate.getNumber(), modelT()); carList. hinzufügen (Auto); carMap.put (Platte, Auto);}); Dies funktionierte perfekt, initialisierte die Auto-Arraylist und bevölkerte dann die Karte zur gleichen Zeit, die so viel effizienter ist als die beiden, die ich vorher gemacht hatte. Danke mein Herr! <3 Anrufe sammeln. –