Ответ
Самый простой способ — использовать HashMap для хранения данных в памяти.
public class SimpleCache<K, V> {
private final Map<K, V> cache = new HashMap<>();
public void put(K key, V value) {
cache.put(key, value);
}
public V get(K key) {
return cache.get(key);
}
public void remove(K key) {
cache.remove(key);
}
}
Почему это просто, но не всегда достаточно:
- Плюсы: Минимальная реализация, быстрый доступ O(1).
- Минусы:
- Нет ограничения размера (риск
OutOfMemoryError). - Нет политики вытеснения (например, LRU).
- Нет TTL (Time-To-Live) для устаревания записей.
- Не потокобезопасно для
HashMap.
- Нет ограничения размера (риск
Практические улучшения:
- Для потокобезопасности используйте
ConcurrentHashMap. - Для production-систем применяйте специализированные библиотеки:
- Caffeine: Высокопроизводительный, современный кэш.
- Guava Cache: От Google, богатый API (размер, TTL, статистика).
Пример с ConcurrentHashMap и LRU-подобным поведением:
public class SimpleConcurrentCache<K, V> {
private final ConcurrentHashMap<K, V> cache = new ConcurrentHashMap<>();
private final int maxSize;
private final LinkedBlockingQueue<K> order = new LinkedBlockingQueue<>();
public SimpleConcurrentCache(int maxSize) { this.maxSize = maxSize; }
public void put(K key, V value) {
if (cache.size() >= maxSize) {
K oldestKey = order.poll(); // Удаляем самый старый ключ
if (oldestKey != null) cache.remove(oldestKey);
}
cache.put(key, value);
order.offer(key);
}
// ... get, remove
}