Как кэшировать данные HashMap для "n" числа итераций
Я получил этот вопрос от одного из моих друзей.
Проблема) Я хочу написать класс, который может кэшировать данные для "n" итераций для каждого ключа и после чего он будет извлекать данные из базы данных. После повторного извлечения данных из базы данных для этого ключа он должен извлекать данные только после итерации "n". Для каждой выборки из базы данных или кэша количество итераций должно быть уменьшено.
Вопрос 1) Как лучше всего расширить HashMap или написать класс, содержащий HashMap? Вопрос 2) Напишите код для вышеуказанной проблемы.
Я написал код ниже. Пожалуйста, предложите мне лучший подход для этого.
public class CacheHashMap {
private int iterationValue = 3;
static Map<String, String> dbSimulator = new HashMap<String, String>();
private Map<String, String> cacheMap;
private Map<String, Integer> iterationMap;
static{
dbSimulator.put("Vijay","VJ");
dbSimulator.put("Smith","SM");
dbSimulator.put("Raj","RJ");
}
public CacheHashMap(Map valueMap, int n) {
this.iterationValue = n;
if(null != valueMap){
this.cacheMap = valueMap;
this.iterationMap = new HashMap<String, Integer>();
for(Map.Entry<String, String> entry:cacheMap.entrySet()){
iterationMap.put(entry.getKey(), iterationValue);
}
}
}
public String getValue(String key){
if(null != cacheMap && null != iterationMap){
if(cacheMap.containsKey(key)){
if(0 == iterationMap.get(key)){
cacheMap.put(key, dbSimulator.get(key));
iterationMap.put(key, (iterationValue-1));
return cacheMap.get(key);
}else{
iterationMap.put(key, (iterationMap.get(key)-1));
return cacheMap.get(key);
}
}else{
cacheMap.put(key, dbSimulator.get(key));
iterationMap.put(key, (iterationValue-1));
return cacheMap.get(key);
}
}
return "No data found. Please enter a valid key";
}
public void printCacheMap(){
System.out.println("==================================================================");
for(Map.Entry<String, String> entry:cacheMap.entrySet()){
System.out.println("Cache Map Data\tKey:: " + entry.getKey() + "\tValue:: " + entry.getValue());
}
}
public void printIterationMap(){
System.out.println("==================================================================");
for(Map.Entry<String, Integer> entry:iterationMap.entrySet()){
System.out.println("Iteration Map Data\tKey:: " + entry.getKey() + "\tValue:: " + entry.getValue());
}
}
}
public class CacheHashMapExecutor {
public static void main(String[] args) {
Map<String, String> myMap = new HashMap<String, String>();
CacheHashMap cacheHashMap = new CacheHashMap(myMap, 3);
cacheHashMap.getValue("Vijay");cacheHashMap.printCacheMap();cacheHashMap.printIterationMap();
cacheHashMap.getValue("Raj");cacheHashMap.printCacheMap();cacheHashMap.printIterationMap();
cacheHashMap.getValue("Smith");cacheHashMap.printCacheMap();cacheHashMap.printIterationMap();
cacheHashMap.getValue("Vijay");cacheHashMap.printCacheMap();cacheHashMap.printIterationMap();
cacheHashMap.getValue("Raj");cacheHashMap.printCacheMap();cacheHashMap.printIterationMap();
cacheHashMap.getValue("Vijay");cacheHashMap.printCacheMap();cacheHashMap.printIterationMap();
cacheHashMap.getValue("Raj");cacheHashMap.printCacheMap();cacheHashMap.printIterationMap();
cacheHashMap.getValue("Vijay");cacheHashMap.printCacheMap();cacheHashMap.printIterationMap();
cacheHashMap.getValue("Raj");cacheHashMap.printCacheMap();cacheHashMap.printIterationMap();
}
}
1 ответ
1-й вопрос: я бы также написал HashMap вместо его расширения, потому что ваша система кэширования не является HashMap; это просто есть HashMap.
2-й: я бы сделал так:
public class CacheHashMap {
private int iterationValue = 3;
static Map<String, String> dbSimulator = new HashMap<String, String>();
private Map<String, CacheItem> cacheMap = new HashMap<>();
static{
dbSimulator.put("Vijay","VJ");
dbSimulator.put("Smith","SM");
dbSimulator.put("Raj","RJ");
}
public CacheHashMap(int n) {
this.iterationValue = n;
}
public String getValue(String key) {
CacheItem item = cacheMap.get(key);
if (item == null || item.isExpired()) {
// Load from DB
String value = dbSimulator.get(key);
cacheMap.put(key, new CacheItem(iterationValue, value));
return value;
} else {
return item.getValue();
}
}
private class CacheItem {
private int iteration;
private String value;
public CacheItem(int iteration, String value) {
this.iteration = iteration;
this.value = value;
}
public boolean isExpired() {
iteration--;
return iteration < 0;
}
public String getValue() {
return value;
}
}
}
Идея состоит в том, чтобы иметь внутренний класс "CacheItem", который не позволяет вам поддерживать 2 разные карты с риском наличия несовместимых ключей. И, кроме того, в алгоритме чтения / записи в кэш есть некоторые улучшения.