2014-11-25 15 views
15

Niedawno odkryłem, że chcę wersji putIfAbsent (...) w java.util.Map, że możesz podać jakąś metodę fabryczną, aby utworzyć obiekt, jeśli jeszcze go nie ma. Uprościłoby to wiele kodu.Dlaczego Java nie ma metody putIfAbsent (klucz, dostawca) w Mapie?

Oto mój zmodyfikowany interfejs:

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; 
    } 

} 

Teraz moje pytanie: Czy istnieje inny (łatwiej) sposób to zrobić albo ja po prostu pomijane coś w Java API?

+4

FWIW, ['Map # putIfAbsent'] (http://docs.oracle.com/javase/8/docs/api/java/util/Map.html#putIfAbsent-K-V-) został dodany za pomocą Java8. – fxm

+0

w języku Java 1.8 istnieje V putIfAbsent (klucz K, wartość V) –

+0

Wiem, ale pozwala tylko na dostarczenie obiektu zamiast metody dostawcy. –

Odpowiedz

17

Czy nie jest computeIfAbsent czego chcesz?

Jeśli określony klucz nie jest już powiązana z wartością (lub jest odwzorowywane na null), próbuje obliczyć jego wartość używając daną funkcję mapowania i wejdzie ona w tej mapie chyba null.

Wdrożenie jest coś takiego:

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

Więc to nie jest dokładnie to Supplier<V> podpis już pisał, ale blisko tego. Posiadanie klucza jako argumentu w funkcji mapowania zdecydowanie ma sens.

+0

Ah. Przeoczyłem to. Dzięki :) –

+0

Tak. Klucz jako argument ma więcej sensu, to prawda. Przyjmuję tę odpowiedź tak szybko, jak tylko mogę. –

+0

Jakieś rozwiązanie dla użytkowników Java 7? – shlatchz

Powiązane problemy