Creare Una Cache con Java

Quante volte vi sarà capitato di dover creare una “semplice” Cache? Le Librerie che implementano questo comportamento esistono ma a volte sono troppo complicate da implementare… vediamo allora come implementarla con pochissime righe di codice ed usando solo la libreria standard.

La classe che andremo a creare estende la classe LinkedHashMap<T, K> questo tipo di mappa espone il metodo protected boolean removeEldestEntry che risponde alla domanda tolgo l’ultima entry inserita?

Vediamo come abbiamo implementato la classe per rispondere alla nostra esigenza di creare una cache con politica FIFO

public class Cache<T, K> extends LinkedHashMap<T, K> {

private int maxSize = 1;

public Cache(int maxSize) {
this.maxSize = maxSize;
}

@Override
protected boolean removeEldestEntry(java.util.Map.Entry<T, K> eldest) {
return size() > this.maxSize;
}

}

et voilà il gioco è fatto…. vediamo come funziona:

public static void main(String[] args) {

//Creo una cache che contiene fino a 4 elementi

Map<String, Integer> cache = new Cache<String, Integer>(3);

cache.put(“INBOX-1”, 1);
cache.put(“INBOX-2”, 2);
cache.put(“INBOX-3”, 3);
cache.put(“INBOX-4”, 4);

System.out.println(cache);

}

come output abbiamo

{INBOX-2=2, INBOX-3=3, INBOX-4=4}

La chiave piu vecchia INBOX-1 è stata eliminata…. spada no! ;-)

Ma miglioriamo il tutto, invece che FIFO vogliamo che scelga quella che ha l’ultimo accesso più datato poche modifiche al codice ed il gioco è fatto:

nella classe cache aggiungiamo l’override del metodo get in modo da far andare quella acceduta come ultima in classifica

public class Cache<T, K> extends LinkedHashMap<T, K> {
private int maxSize = 1;
//Questo è il metodo aggiunto rispetto a prima
@Override
public K get(Object key) {
K tmpObj = super.get(key);

super.remove(key);

super.put((T)key, tmpObj);

return super.get(key);
}

public Cache(int maxSize) {
this.maxSize = maxSize;
}

@Override
protected boolean removeEldestEntry(java.util.Map.Entry<T, K> eldest) {
return size() > this.maxSize;
}
}

lanciamo questo test

public static void main(String[] args) {

Map<String, Integer> cache = new Cache<String, Integer>(3);

cache.put(“INBOX-1”, 1);
cache.put(“INBOX-2”, 2);
cache.put(“INBOX-3”, 3);
cache.get(“INBOX-1”);
cache.put(“INBOX-4”, 4);

System.out.println(cache);

}

e avremo come output

{INBOX-3=3, INBOX-1=1, INBOX-4=4}

Come ci aspettavamo è stata tolta la seconda entry…..

spada no?

Potere di JAVA ;-)