Chinaunix首页 | 论坛 | 博客
  • 博客访问: 666309
  • 博文数量: 220
  • 博客积分: 10487
  • 博客等级: 上将
  • 技术积分: 2072
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-09 00:25
文章分类

全部博文(220)

文章存档

2012年(5)

2011年(38)

2010年(135)

2009年(42)

我的朋友

分类: Java

2010-05-25 23:30:52

比较器:根据属性来比较两个对象大小

package com.zte.frame.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Comparator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * 比较器:根据属性来比较两个对象大小;

 * 实现机制:反射get方法,获取属性值,再调用属性的compareTo方法比较大小

 * 1.对属性类型的要求:实现Comparable接口,具体实现了compareTo方法的
 * 合法类型有String,Date,Integer,Long,Double ...

 * 2.对比较的对象的要求,要比较的属性实现了get方法,且严格按照驼峰式命名方法实现
 * 应用实例:

 *
 *         List lst = new ArrayList;

 *      //ouName是OutBankBookPageBean的一个属性名,CommonByAttrComparator.asc升序排列

 *      CommonByAttrComparator comparator = new CommonByAttrComparator("ouName",CommonByAttrComparator.asc)

 *        Collections.sort(resultLst, comparator);

 *

 *
 * @author xiadehu
 * @version 1.0 13/18/2009
 *
 */
public class CommonByAttrComparator implements Comparator{
    
    private Log log = LogFactory.getLog(getClass());

    /*
     * 升序排列
     */
    public static final int asc=0;
    /*
     * 降序排列
     */
    public static final int desc = 1;
    /*
     * 排序类型,升序/降序
     */
    private int sortType=0;
    /*
     * 要排序的属性名
     */
    private String attrName = null;
    /*
     * get常量
     */
    private String get = "get";
    /*
     * 科学计数法正则表达式,诸如"1,222,002.00"类的字符串
     */
    private String DECIMAL_PATTERN = "-?(\\d{1,3},{1})*\\d{1,3}\\.{1}\\d{2}";
    /**
     * 构造函数
     * @param attrName
     * @param sortType
     */
    public CommonByAttrComparator(String attrName,int sortType){
        this.sortType=sortType;
        this.attrName=attrName;
    }
    /**
     * 通过反射实现比较方法
     */
    @SuppressWarnings("unchecked")
    public int compare(Object src, Object desc) {
        if(src==desc){
            return 0;
        }
        if(src==null){
            return -1;
        }
        if(desc==null){
            return 1;
        }
        try {
            //获取get方法
            Method mSrc = src.getClass().getMethod(getMethodName());
            Method mDesc = desc.getClass().getMethod(getMethodName());
            Comparable srcValue = (Comparable) mSrc.invoke(src, new Object[]{});
            Comparable descValue = (Comparable) mDesc.invoke(desc, new Object[]{});
           
            //判断通过get方法获取的值是否为空
            if(srcValue==descValue){
                return 0;
            }
            if(srcValue==null){
                return -1;
            }
            if(descValue==null){
                return 1;
            }
           
            //针对字符串作的增强排序,如果是金额类型字符串则按照金额大小排序
            int result = adviceCompareNumString(srcValue,descValue);
            if(Integer.MIN_VALUE!=result){
                return result;
            }
           
            //调用compareTo方法,获取比较结果
            int compareValue = srcValue.compareTo(descValue);
            //如果为asc排序,则直接返回比较值,否则取反结果并返回
            return sortType==asc?compareValue:reverseValue(compareValue);
        } catch (SecurityException e) {
            log.error(e.getMessage(),e);
        } catch (NoSuchMethodException e) {
            log.error(e.getMessage(),e);
        } catch (IllegalArgumentException e) {
            log.error(e.getMessage(),e);
        } catch (IllegalAccessException e) {
            log.error(e.getMessage(),e);
        } catch (InvocationTargetException e) {
            log.error(e.getMessage(),e);
        }
        return 0;
    }
   
    /**
     *
     * 方法注释: 针对金额字符串作的增强排序,如果是金额类型字符串则按照金额大小排序 .

     * xiadehu 2009-8-20 下午06:00:56
     * @param srcValue
     * @param descValue
     * @return
     */
    private int adviceCompareNumString(Comparable srcValue, Comparable descValue) {
        try {
            if(srcValue instanceof String && descValue instanceof String){//如果srcValue和descValue均为String
                String src = (String) srcValue;
                String desc = (String) descValue;
                if(src.matches(DECIMAL_PATTERN)&&desc.matches(DECIMAL_PATTERN)){//如果src和desc均为科学计数式字符串
                    Double srcD = Double.parseDouble(src);
                    Double descD = Double.parseDouble(desc);
                    int value = srcD.compareTo(descD);
                    return sortType==asc?value:reverseValue(value);
                }
            }
        } catch (NumberFormatException e) {
            log.info("字符串长度过长,未采取增强金额比较法进行比较");
        }
        return Integer.MIN_VALUE;
    }
    /**
     *
     * 方法注释: 取反比较结果 .

     * xiadehu 2009-8-13 上午10:38:36
     * @param value
     * @return
     */
    private int reverseValue(int value){
        return (-1)*value;
    }
   
    /**
     *
     * 方法注释: 通过属性获取get方法名 .

     * xiadehu 2009-8-13 上午10:38:54
     * @return
     */
    private String getMethodName(){
        if(this.attrName==null || attrName.trim().length()==0){
            throw new RuntimeException("比较器内部错误,要比较的属性不能为null或空");
        }
        return get+attrName.substring(0, 1).toUpperCase().concat(attrName.substring(1,attrName.length()));
    }
    public String getAttrName() {
        return attrName;
    }
    public void setAttrName(String attrName) {
        this.attrName = attrName;
    }
    public int getSortType() {
        return sortType;
    }
    public void setSortType(int sortType) {
        this.sortType = sortType;
    }
   
}
阅读(983) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~