Sto scrivendo un semplice HashMap
cache basata su che funziona come segue:Java - Estendere HashMap - Oggetto vs. generici comportamento
- Se la richiesta
key
è nella cache, restituisce il suovalue
. - Se la richiesta
key
non è lì, eseguire un metodo che producevalue
sulla base dikey
, memorizzare sia, tornarevalue
.
Il codice:
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);
}
E 'piuttosto semplice e funziona bene. Tuttavia, I odio la decisione di Sun per get()
di prendere uno Object
come argomento e non K
. Ho letto abbastanza su questo per sapere che ha qualche fondamento logico (con cui non sono d'accordo, ma questa è un'altra storia).
Il mio problema è nella riga commentata, perché sembra che il cast abbia deselezionato. A causa della cancellazione del tipo, non è possibile verificare se key
è di tipo K
(che è necessario per la corretta funzionalità put()
) e il metodo è, pertanto, soggetto a errori.
Una soluzione potrebbe essere quella di passare da "è un" a "ha un" HashMap
rapporto che è molto più bello e pulito, ma poi Cache
non può attuare Map
che sarebbe bello per diversi motivi. Il codice:
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);
}
Qualcuno può venire con qualsiasi altra soluzione (anche hacker), in modo da poter mantenere Cache
di essere un Map
ed essere ancora al sicuro nei termini di get(Object key)
e put(K key, V val)
tipo?
L'unica cosa che posso pensare è di fare un altro metodo chiamato getValue(Key k)
che delegherebbe a get(Object key)
, ma poi non posso costringere nessuno a usare il nuovo metodo invece del solito.
È possibile implementare 'getA' o' myget' Non è possibile modificare il comportamento di Map.get() come non si può forzare direttamente la ricompilazione del codice che usa l'interfaccia invece della propria classe. –