2014-09-27 70 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