Chinaunix首页 | 论坛 | 博客
  • 博客访问: 41417
  • 博文数量: 17
  • 博客积分: 69
  • 博客等级: 民兵
  • 技术积分: 95
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-04 02:38
文章分类
文章存档

2012年(13)

2011年(4)

我的朋友
最近访客

分类:

2012-01-12 22:05:19

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;

                  }

                  ///beangetXXX方法

                  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]);

                  ///beanisXXX方法

                  }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,它的键是对象的类名,值是该对象的所有getis方法和对应的名称(Map,Map> cacheBean)

 

但缓存直接使用map对象,并不是太合理。普通的缓存都是采用tair来做,设置超时时间,这样既把压力转移到tair来做而且有个很好的淘汰机制。

然后这种策略不是适用所有场景,有时候本地的缓存会更加高效。

作为本地缓存用Collections.synchronizedMap(new LinkedHashMap())Collections.synchronizedMap(new SoftHashMap())LinkedHashMap可以保证map对象有序,基于这个特点可以设计出基于最久未使用的淘汰策略。而对于softHashMap,它属于软引用,有利于优化内存管理。

 

java中,引用分为四种。

StrongReference:就是普通的引用,它不释放的话,内存是无法被回收的。

SoftReference:软引用 它在内存不足时就会被回收。这种类型做为缓存比较合适,内存不够时不会影响系统运行。但是建立这样的对象开销也比较大,而且使用的话是和引用队列一起使用比较好。(这个的使用大家可以查阅一下资料)

WeakReference:弱引用 只具有弱引用对象,它不影响程序运行。

PhantomReference:虚引用,仅有虚引用随时会被回收。

 

自己实现了一个简单的缓存淘汰方法,这个方法只有在缓存满时才会执行:

缓存类型: Map map;

                      CacheItem 包含key,value,t (包含一个完整的键值对和最后更新的时间,这个时间最好是自己维护的自增长字段)

实现方法:

1.       建一个最大堆,大小为512个数据,依次插入所有的缓存项,直至堆中包含512个数据。

2.       继续插入时,对于新来的缓存项与堆顶比较t的大小,若新的缓存项t比较小,就去除堆顶,将新来的缓存项加入,重新调整堆。

3.       依次插入缓存项,直至所有的项都遍历完成。

4.       这样留在堆里就是最小的512项缓存,最后依次清理这些项就可以了。

 

 

    Collection c = map.values();

    Iterator it = c.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());

    }

阅读(858) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~