2014-11-25 16 views
15

Recentemente mi sono ritrovato a volere una versione di putIfAbsent (...) in java.util.Map a cui è possibile fornire un qualche tipo di metodo factory per creare un'istanza di un oggetto se non è già presente. Ciò semplificherebbe molto codice.Perché Java non ha un metodo putIfAbsent (chiave, fornitore) in Mappa?

Ecco la mia interfaccia modificata:

import java.util.Map; 
import java.util.function.Supplier; 

/** 
* Extension of the Map Interface for a different approach on having putIfAbsent 
* 
* @author Martin Braun 
*/ 
public interface SupplierMap<K, V> extends Map<K, V> { 

    public default V putIfAbsent(K key, Supplier<V> supplier) { 
     V value = this.get(key); 
     if(value == null) { 
      this.put(key, value = supplier.get()); 
     } 
     return value; 
    } 

} 

Ora la mia domanda: C'è un altro (più facile) modo di fare questo o sono io trascurato qualcosa nella API Java?

+4

FWIW, ['Map # putIfAbsent'] (http://docs.oracle.com/javase/8/docs/api/java/util/Map.html#putIfAbsent-K-V-) è stato aggiunto con Java8. – fxm

+0

in Java 1.8 c'è V putIfAbsent (chiave K, valore V) –

+0

Lo so, ma consente solo di fornire un oggetto invece di un metodo fornitore. –

risposta

17

non è computeIfAbsent quello che vuoi?

Se la chiave specificata non è già associato un valore (o è mappato a null), tenta di calcolare il valore con la data funzione di mappatura ed entra in questa mappa meno nullo.

Attuazione è qualcosa di simile:

if (map.get(key) == null) { 
    V newValue = mappingFunction.apply(key); 
    if (newValue != null) { 
     map.put(key, newValue); 
    } 
} 

Quindi non è esattamente la firma Supplier<V> che hai postato, ma vicino a quello. Avere la chiave come argomento nella funzione di mappatura ha decisamente senso.

+0

Ah. Ho trascurato quello. Grazie :) –

+0

Sì. La chiave come argomento ha più senso, è vero. Accetterò questa risposta il più presto possibile. –

+0

Qualche soluzione per gli utenti di Java 7? – shlatchz