分类:
2012-01-12 22:05:19
原文地址:【代码回顾】bean2map工具类 作者:ranson_zop
在api中,许多实现都是去自己手动去构造map对象作为输出,存在很多重复性劳动,由此设计bean2map工具类。
Bean2map 功能:
将传入的对象转化为map对象
* 转化规则为:isXXX=value转化为XXX=value这样的键值对
* getXXX=value转化为XXX=value这样的键值对
* 对于有参数的所有方法都不会进行转化
* 对于异常情况返回为null
* 对于无法转化的对象返回也为null
* 无法转化的对象包括(int,string,double,float,long,list,collection,数组,set)
用反射来实现此功能:
1. 过滤所以非bean的类
2. 获取该bean的所有方法
3. 遍历所有方法,对于不是合法的方法进行过滤
4. 对于get方法进行提取
5. 对于is方法进行提取
if(classFilter.doFilter(objCls))
{
return null;
}
Class> objCls = obj.getClass();
Method[] objMth = objCls.getMethods();
cacheMap = new HashMap
for(int i = 0;i < objMth.length; i ++){
String name = objMth[i].getName();
StringBuffer sb = new StringBuffer();
//过滤系统方法
if(methFilter.doFilter(objMth[i])){
continue;
}
///bean的getXXX方法
if(objMth[i].getName().startsWith(GET)){
sb.append(name.substring(3, 4).toLowerCase());
sb.append(name.substring(4));
result.put(sb.toString(), objMth[i].invoke(obj, null));
cacheMap.put(sb.toString(), objMth[i]);
///bean的isXXX方法
}else if(objMth[i].getName().startsWith(IS))
{
sb.append(name.substring(2, 3).toLowerCase());
sb.append(name.substring(3));
result.put(sb.toString(), objMth[i].invoke(obj, null));
cacheMap.put(sb.toString(), objMth[i]);
}
为了提高效率,加了一个缓存,缓冲的是一个map,它的键是对象的类名,值是该对象的所有get与is方法和对应的名称(Map
但缓存直接使用map对象,并不是太合理。普通的缓存都是采用tair来做,设置超时时间,这样既把压力转移到tair来做而且有个很好的淘汰机制。
然后这种策略不是适用所有场景,有时候本地的缓存会更加高效。
作为本地缓存用Collections.synchronizedMap(new LinkedHashMap())或Collections.synchronizedMap(new SoftHashMap())。LinkedHashMap可以保证map对象有序,基于这个特点可以设计出基于最久未使用的淘汰策略。而对于softHashMap,它属于软引用,有利于优化内存管理。
在java中,引用分为四种。
StrongReference:就是普通的引用,它不释放的话,内存是无法被回收的。
SoftReference:软引用 它在内存不足时就会被回收。这种类型做为缓存比较合适,内存不够时不会影响系统运行。但是建立这样的对象开销也比较大,而且使用的话是和引用队列一起使用比较好。(这个的使用大家可以查阅一下资料)
WeakReference:弱引用 只具有弱引用对象,它不影响程序运行。
PhantomReference:虚引用,仅有虚引用随时会被回收。
自己实现了一个简单的缓存淘汰方法,这个方法只有在缓存满时才会执行:
缓存类型: Map
CacheItem 包含key,value,t (包含一个完整的键值对和最后更新的时间,这个时间最好是自己维护的自增长字段)
实现方法:
1. 建一个最大堆,大小为512个数据,依次插入所有的缓存项,直至堆中包含512个数据。
2. 继续插入时,对于新来的缓存项与堆顶比较t的大小,若新的缓存项t比较小,就去除堆顶,将新来的缓存项加入,重新调整堆。
3. 依次插入缓存项,直至所有的项都遍历完成。
4. 这样留在堆里就是最小的512项缓存,最后依次清理这些项就可以了。
Collection
Iterator
Heap heap = new Heap();
CacheItem head;
/*
* 找出所有缓存项中最早的512项
*/
for (int i = 0; it.hasNext();i++) {
if(i < size){
heap.insert(it.next());
}else{
CacheItem temp = it.next();
head = (CacheItem)heap.peek();
if(head.getT() > temp.getT()){
heap.extract();
heap.insert(temp);
}
}
}
/*
* 清除这些过早的缓存项
*/
while(heap.peek()!=null){
CacheItem item = (CacheItem)heap.extract();
map.remove(item.getKey());
}