2017-12-21 111 views
6

Jak mogę wykonać funkcję na wartości mapy tylko wtedy, gdy jest obecna, bez wprowadzania żadnych zmian na mapie? Chcę to zrobić przy użyciu stylu deklaratywnego "Java 8", porównywalnego z Optional.ifPresent().Mapa funkcja ifPresent

Moje przypadek użycia jest następujący:

otrzymam aktualizacje (nowe lub usunięte) do obiektów w części, chcę zarejestrować się rodzica te aktualizacje. Dla księgowych Mam następujący:

Map<ParentId, Parent> parents = ... 

Po otrzymaniu nowego dziecka I wykonaj następujące czynności:

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

Jednak do usuwania nie mogę znaleźć funkcję deklaratywny. Prosta chciałbym zaimplementować to jako:

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

Albo mogę owinąć wartość w Optional:

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

Należy zauważyć, że dominująca nie jest prosta lista, zawiera więcej niż tylko dzieci. Więc dodaje nie działa (bo removeChild() nie zwraca Parent):

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

Jak mogę to zrobić, czy nie istnieje odpowiednik Optional.ifPresent()?

+0

one sposobem z opcja jest chyba najprostszy podejście i najczystszych, może myśleć o – Lino

+0

Co się dzieje, gdy rodzic kończy się bez dzieci? Czy chcesz usunąć tego rodzica z mapy, czy też jest to w porządku, jeśli rodzic nie ma dzieci? –

+0

@FedericoPeraltaSchaffner Nic z tego przykładu (w moim przypadku, ponieważ istnieją również inne dane, które muszą zostać zapisane). – Thirler

Odpowiedz

5

myślę rozwiązanie Optional wygląda ok, ale dla

następujące nie działa (bo removeChild() nie zwraca rodzica): parents.computeIfPresent(child.getParentId(), (k, v) -> v.removeChild());

można przedłużyć lambda to

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

Powiedziałbym, że prosta droga jest w tym przypadku najwyraźniejsza, Poszedłbym z tym.

+2

Warto zauważyć, że nawet jeśli to użycie "computeIfPresent" skutecznie nie zmieni mapy, niezmienne mapy mogą je odrzucić z "UnsupportedOperationException", nawet nie sprawdzając, czy funkcja oceni nową wartość. – Holger

+0

@Holger to bardzo dobry punkt, kolejny powód do pocałunku. – daniu

1

Jeśli nie ma żadnych skutków ubocznych do tworzenia niepotrzebnych rodzica, a nie jest wyjątek, usuwając nieobecnego dziecka, można użyć:

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

@Lino, to doda wartość do mapy, jeśli nie była obecna. – Thirler

+0

@Thirler masz rację – Lino