2014-09-27 62 views
0

我从我的一个朋友那里得到了这个问题。如何缓存“n”次迭代的HashMap数据

问题)我想写一个类,它可以为每个键缓存“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(); 
    } 

} 
+0

很好,你没有选择扩展'HashMap',而是编写它 - 这是正确的选择。然而,保持平行集合是许多新手程序员的错误,并显示“对象恐惧症”。将单个缓存值的行为包装到“CacheValue”类中。 – 2014-09-27 11:11:41

+2

这个问题似乎是题外话题,因为它要求代码审查,因此更适合[代码审查](http://codereview.stackexchange.com/)。 – 2014-09-27 11:12:19

+0

@BoristheSpider感谢您的建议。我对于stackoverflow很新,下次我会在代码审查时保留这类问题。 – 2014-09-27 14:20:04

回答

0

1问题:我也缀以HashMap中,而不是扩展它,因为你的缓存系统不是一个HashMap;它只是一个HashMap。

第二:我会做这样的:

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个不同的地图,具有按键不一致的风险。此外,我认为在读取/写入缓存的算法中有一些改进。

+0

感谢您的建议。 – 2014-09-27 14:16:56