Estoy escribiendo un simple HashMap
caché basada en que funciona de la siguiente manera:Java - Ampliación HashMap - Objeto vs comportamiento genéricos
key
Si el pedido es en la memoria caché, presentara suvalue
.- Si el pedido no es
key
allí, ejecutar un método que producevalue
basado enkey
, almacenar tanto, volvervalue
.
El código:
import java.util.HashMap;
abstract class Cache<K, V> extends HashMap<K, V> {
@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);
}
Es bastante sencillo y funciona bien. Sin embargo, I odio la decisión del Sol para get()
para tomar como argumento Object
y no K
. He leído lo suficiente al respecto como para saber que tiene algún fundamento (con el que no estoy de acuerdo, pero esa es otra historia).
Mi problema está en la línea comentada, porque parece que el molde tiene para ser desmarcado. Debido al borrado de tipo, no hay manera de que pueda verificar si key
es del tipo K
(que es necesario para la funcionalidad adecuada de put()
) y el método es, por lo tanto, propenso a errores.
Una solución sería cambiar de "es una" a "tiene un" HashMap
relación que es mucho más agradable y limpio, pero luego no se puede poner en práctica Cache
Map
que sería bueno por varias razones. El código:
import java.util.HashMap;
import java.util.Map;
abstract class Cache<K, V> {
private final Map<K, V> map = new HashMap<K, V>();
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);
}
¿Alguien puede llegar a cualquier otra solución (incluso hacker), de modo que pudiera mantener Cache
a ser un Map
y todavía ser seguro en los términos de get(Object key)
y put(K key, V val)
tipo?
Lo único que se me ocurre es hacer otro método llamado, por ejemplo, getValue(Key k)
que delegaría en get(Object key)
, pero no puedo obligar a nadie a usar el nuevo método en lugar del habitual.
Puede implementar 'getA' o' myget' No puede cambiar el comportamiento de Map.get() ya que no puede forzar código que utiliza la interfaz en lugar de su clase directamente para ser recompilado. –