【问题标题】:How to cache HashMap data for "n" number of iteration如何为“n”次迭代缓存HashMap数据
【发布时间】:2014-11-22 07:35:52
【问题描述】:

我从我的一位朋友那里得到了这个问题。

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

}

【问题讨论】:

  • 很高兴您没有选择扩展HashMap 而是组合它 - 这是正确的选择。然而,维护并行集合是许多新手程序员的错误,并表现出“对象恐惧症”。将单个缓存值的行为包装到 CacheValue 类中。
  • 这个问题似乎跑题了,因为它要求进行代码审查,因此更适合Code Review
  • @BoristheSpider 感谢您的建议。我对stackoverflow很陌生,下次我会在代码审查中保留这类问题。

标签: java caching hashmap


【解决方案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 个不同的映射,从而避免键不一致的风险。此外,我认为在读取/写入缓存的算法方面也有一些改进。

【讨论】:

  • 感谢您的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 2012-08-03
  • 1970-01-01
  • 2018-01-26
  • 2016-09-08
相关资源
最近更新 更多