在一个简单的java project 中,我们通常很难感受到所谓读取时间的概念。但是在一个相对巨型的工程中,数据来源比较复杂,在某些时候一些处理类中会反复调用某些申请数据的方法,如 getData("dataKey")。该方法可能需要走很长的路才能获得我们所需要的数据,比如从另外一个复杂的XML文件中读取等。为了降低每次getData时那“漫长”的索取时间,以及同样漫长的逻辑轨迹图,我们就可以使用缓存了。
 首先,假设这个getData()方法是放在一个DataHandler之类的类中的。

public class DataHandler {
    public UserData getData(String dataKey){

        // code here is complex enough 

        return null;
    }
}



为了缓存每次getData()获得的新值,我们在DataHandler类中弄一个本地的Map来储存用户取过的Data:

private Map<String,UserData> tempData = new HashMap<String,UserData>();



与此同时,我们另外设计一个getData()的方法,此方法优先从本地的缓存Map中取所要的值,只是在本地没有对应的值时才采用原来的方式”走很远的路“去取值。

public UserData getDataWithTemp(String dataKey){
        if (tempData.containsKey(dataKey)){
            return tempData.get(dataKey);
        }
        UserData newData = getData(dataKey);
        tempData.put(dataKey,newData);
        return newData;
    }

此时缓存就完成了。可以看到这个缓存的Map是动态添加数据的,即用户每次申请一个缓存中不存在的newData的时候才将这个newData放进缓存。与动态缓存相对的一种方式是,在DataHandler初始化的时候就将所有的数据请求好,放在一个大的Map中存储起来,一劳永逸。比如获取所有数据的方法为:

public Map<String,UserData> getAllData(){

        // code here is complex enough

        return new HashMap<String, UserData>();
    }

而在DataHandler类构造的时候(或者其他合适的时候)就将缓存的tempData初始化,如:

public DataHandler() {
        this.tempData = getAllData();
    }




这种一开始就讲所有数据请求得到的方法是不好的。因为对于每一个Data而言,可能包含的属性很多,很全面,而具体的Handler其实只针对AllData中的部分对象经常进行操作,而大部分数据并不是经常需要。因此采用"一劳永逸"的方法浪费了内存,同时,不是按照用户的申请习惯来存储的缓存在查找的时候自然就没有了用户想要的畅快了。