HashMap
cache simple HashMap
sur HashMap
qui fonctionne comme suit:
key
demandée est en cache, renvoyez sa value
. key
demandée n’est pas là, exécutez une méthode qui produit une value
basée sur la key
, stockez les deux et renvoyez une value
. Le code:
import java.util.HashMap; abstract class Cache extends HashMap { @Override public V get(Object key) { if (containsKey(key)) { return super.get(key); } else { V val = getData(key); put((K)key, val); // this is the line I'm discussing below return val; } } public abstract V getData(Object key); }
C’est assez simple et fonctionne bien. Cependant, je déteste la décision du soleil pour get()
de prendre un Object
comme argument et non K
J’en ai assez lu pour savoir qu’il a une raison derrière (avec laquelle je ne suis pas d’accord, mais c’est une autre histoire).
Mon problème est dans la ligne commentée, car il semble que la dissortingbution doit être décochée. En raison de la suppression du type, il est impossible pour moi de vérifier si la key
est de type K
(nécessaire pour la fonctionnalité put()
appropriée) et la méthode est donc sujette aux erreurs.
Une solution serait de passer de “est un” à “a” HashMap
relation HashMap
qui est beaucoup plus agréable et propre, mais alors Cache
ne peut pas implémenter Map
ce qui serait bien pour plusieurs raisons. Le code:
import java.util.HashMap; import java.util.Map; abstract class Cache { private final Map map = new HashMap(); public V get(K key) { if (map.containsKey(key)) { return map.get(key); } else { V val = getData(key); map.put(key, val); return val; } } public abstract V getData(K key); }
Est-ce que n’importe qui peut proposer n’importe quelle autre solution (même bidon), de sorte que je puisse maintenir le Cache
être une Map
et toujours être sûr de taper dans les termes de get(Object key)
et de put(K key, V val)
?
La seule chose à laquelle je peux penser est de créer une autre méthode appelée getValue(Key k)
qui déléguerait pour get(Object key)
, mais je ne peux forcer personne à utiliser la nouvelle méthode à la place de la méthode habituelle.
Nan. Vous avez trouvé la bonne solution en optant pour une relation “a-a”. (Franchement, get
méthode get
calculer une nouvelle valeur s’il n’existait pas déjà est surprenant, constitue une violation du contrat Map
et peut conduire à un comportement extrêmement étrange pour un certain nombre d’autres méthodes. C’est en grande partie pourquoi Guava s’est éloigné. de MapMaker
, qui offrait presque ce comportement exact – car il était tellement criblé de problèmes.)
Cela dit, Guava’s Cache
, par exemple, expose une vue Map
, ce que vous pouvez faire. Cela vous donne la plupart des avantages d’une Map
sans compromettre la sécurité du type.
définitivement la relation has-a est une implémentation correcte. la logique métier de la manière dont la valeur est générée doit être supprimée de la classe de cache.