Java – Extension de HashMap – Comportement des objects par rapport aux génériques

HashMap cache simple HashMap sur HashMap qui fonctionne comme suit:

  1. Si la key demandée est en cache, renvoyez sa value .
  2. Si la 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 asMap() , 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.