How can I avoid repeating code initializing a hashmap of hashmap?

Hernán Eche :

Every client has an id, and many invoices, with dates, stored as Hashmap of clients by id, of a hashmap of invoices by date:

HashMap<LocalDateTime, Invoice> allInvoices = allInvoicesAllClients.get(id);

if(allInvoices!=null){
    allInvoices.put(date, invoice);      //<---REPEATED CODE
}else{
    allInvoices = new HashMap<>();
    allInvoices.put(date, invoice);      //<---REPEATED CODE
    allInvoicesAllClients.put(id, allInvoices);
}

Java solution seems to be to use getOrDefault:

HashMap<LocalDateTime, Invoice> allInvoices = allInvoicesAllClients.getOrDefault(
    id,
    new HashMap<LocalDateTime, Invoice> (){{  put(date, invoice); }}
);

But if get is not null, I still want put (date, invoice) to execute, and also adding data to "allInvoicesAllClients" is still needed. So it doesn't seem to help much.

Jacob G. :

This is an excellent use-case for Map#computeIfAbsent. Your snippet is essentially equivalent to:

allInvoicesAllClients.computeIfAbsent(id, key -> new HashMap<>()).put(date, invoice);

If id isn't present as a key in allInvoicesAllClients, then it'll create mapping from id to a new HashMap and return the new HashMap. If id is present as a key, then it'll return the existing HashMap.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=342031&siteId=1