2017-12-21 3 views
6

Wie kann ich eine Funktion auf einen Wert einer Karte nur ausführen, wenn sie vorhanden ist, ohne Änderungen an der Karte vorzunehmen? Ich möchte dies mit dem 'Java 8' deklarativen Stil, vergleichbar mit Optional.ifPresent().Karte ifPresent Funktion

Mein Anwendungsfall ist wie folgt:

I erhalten Updates (neue oder gelöschte) auf Objekte teilweise ich diese Updates mit ihren Eltern registrieren möchten. Für Buchhaltung habe ich folgendes:

Map<ParentId, Parent> parents = ... 

Wenn ein neues Kind Empfangen ich folgendes tun:

parents.computeIfAbsent(child.getParentId(), k -> new Parent()).addChild(child)); 

jedoch zum Entfernen ich nicht die deklarative Funktion finden. Geradlinig würde ich dies umzusetzen, wie:

if(parents.containsKey(child.getParentId()) 
{ 
    parents.get(child.getParentId()).removeChild(child); 
} 

Oder ich könnte den Wert in einer Optional wickeln:

Optional.ofNullable(parents.get(child.getParentId()).ifPresent(p -> p.removeChild(child)); 

Beachten Sie, dass Eltern nicht eine einfache Liste ist, enthält es mehr als nur Kinder. So ist die folgende nicht funktioniert (weil removeChild() nicht zurück ein Parent):

parents.computeIfPresent(child.getParentId(), (k, v) -> v.removeChild()); 

Wie kann ich dies tun, oder gibt es kein Äquivalent zu Optional.ifPresent()?

+0

Sie Art und Weise mit optional ist wahrscheinlich der einfachste Ansatz und die sauberste i Denken Sie an – Lino

+0

Was passiert, wenn der Elternteil ohne Kinder endet? Müssen Sie dieses Elternteil ebenfalls aus der Karte entfernen, oder ist es in Ordnung, wenn das Elternteil ohne Kinder bleibt? –

+0

@FedericoPeraltaSchaffner Nichts für dieses Beispiel (in meinem Fall, da auch noch andere Daten gespeichert werden müssen). – Thirler

Antwort

5

Ich denke, Ihre Optional Lösung sieht ok, aber für

folgende nicht funktioniert (weil removeChild() ein Elternteil nicht zurück): parents.computeIfPresent(child.getParentId(), (k, v) -> v.removeChild());

Sie verlängern könnte der Lambda zu

Ich würde sagen, dass der geradlinige Weg in diesem Fall jedoch am klarsten ist, Ich würde damit gehen.

+2

Es ist erwähnenswert, dass selbst wenn diese 'computeIfPresent'-Verwendung die Map nicht effektiv ändert, unveränderliche Maps es möglicherweise mit einer' UnsupportedOperationException' ablehnen, ohne zu prüfen, ob die Funktion einen neuen Wert auswerten würde. – Holger

+0

@Holger das ist ein sehr guter Punkt, ein weiterer Grund für KISS. – daniu

1

Wenn es keine Nebenwirkungen sind ein unnötig Eltern zu schaffen und keine Ausnahme durch Entfernen ein abwesendes Kindes geworfen wird, könnten Sie verwenden:

parents.getOrDefault(child.getParentId(), new Parent()).removeChild(child); 
+0

@Lino, dies wird den Wert der Karte hinzufügen, wenn sie nicht vorhanden war. – Thirler

+0

@Thirler du hast Recht – Lino