Pergunta sobre a implementação LRU cache em Java
Pergunta
O exemplo padrão para implementar LRU cache em Java aponta para a url exemplo depot http://www.exampledepot.com/egs/java.util/coll_Cache. html
Como é removeEldestEntry chamado por padrão após apenas adicionando uma nova entrada no trecho de código a seguir?
final int MAX_ENTRIES = 100;
Map cache = new LinkedHashMap(MAX_ENTRIES+1, .75F, true) {
// This method is called just after a new entry has been added
public boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_ENTRIES;
}
};
// Add to cache
Object key = "key";
cache.put(key, object);
// Get object
Object o = cache.get(key);
if (o == null && !cache.containsKey(key)) {
// Object not in cache. If null is not a possible value in the cache,
// the call to cache.contains(key) is not needed
}
// If the cache is to be used by multiple threads,
// the cache must be wrapped with code to synchronize the methods
cache = (Map)Collections.synchronizedMap(cache);
Solução
Neste exemplo, o LinkedHashMap
está sendo ampliado com um " " classe interna anônima.
O método removeEldestEntry
está substituindo a versão de super-classe, que retorna sempre false
(indicando a entrada mais velho não deve ser removida). A versão imperiosas retornos true
se o tamanho do mapa exceder o limite, o que indica que a entrada mais antiga deve ser removida.
Outras dicas
Por API Java para LinkedHashMap
:
O método
removeEldestEntry(Map.Entry)
pode ser substituída para impor uma política para remover mapeamentos obsoletos automaticamente quando novos mapeamentos são adicionadas ao mapa.
Especificamente:
Este método é invocado por
put
eputAll
depois de inserir uma nova entrada para o mapa.
Também nota:
Este método normalmente não modifica o mapa de qualquer forma, em vez permitindo o mapa para modificar-se como dirigido por seu valor de retorno. É permitido para este método para modificar o mapa diretamente, mas se ele faz isso, ele deve retornar falso (o que indica que o mapa não deve tentar qualquer modificação posterior). Os efeitos da retornando true depois de modificar o mapa de dentro este método não são especificadas.
A documentação da classe LinkedHashMap afirma que irá chamar o removeEldestEntry () método em momentos apropriados. No código acima nós fornecemos um anônimo "estende" da classe LinkedHashMap que prevê expressamente a nossa implementação desse método.