比较器:基本类型单一通用比较器

当我们获得一个List后,如果希望它是按容器中,元素的某种属性排序的话,我们是可以通过

Collections.sort(myList, new my比较器())进行排序的。

但问题是,不同的属性要写不同的比较器,不同的类也要写比较器。

如果不希望重复劳动,就需要一个通用的比较器,所以写了以下代码。

 

我自己命名的:基本类型单一通用比较器 是指

(1)基本类型:元素的属性必须是:boolean,byte,char,int,long,float,double及他们的包装类 + String,Date,BigDecimal这几种类型

(2)所谓的单一(Single)是指:只比较类中的某一属性(不像SQL 的odrder by,后面可以跟n个,以后会扩展)

(3)通用(Universal)是指:任何类都可以用(希望如此)

 

废话少说,代码如下:

public final class BasicDataSingleUniversalComparator implements Comparator<Object> {

	private Class<?> c; //要比较的类
	private String fieldName; //根据类的哪个属性比较
	private Field field;
	private String filedTypeName; //属性类型名称
	//private Class<Object> attributeClass; //要比较的类的属性的类型
	private boolean isAsc; //比较结果是升序 or倒序, true:根据类属性自然比较结果的升序排列, false:根据类属性自然比较结果的倒序排列
	private int asc;

	private final static Map<String, String> compareMethods;
	
	static {
		compareMethods = new HashMap<String, String>();
		// * boolean,byte,char,int,long,float,double及他们的包装类 + String,Date这几种类型
		compareMethods.put("boolean", "compareBoolean");
		compareMethods.put("byte", "compareByte");
		compareMethods.put("char", "compareCharacter");
		compareMethods.put("character", "compareCharacter");
		compareMethods.put("int", "compareInteger");
		compareMethods.put("integer", "compareInteger");
		compareMethods.put("long", "compareLong");
		compareMethods.put("float", "compareFloat");
		compareMethods.put("double", "compareDouble");
		compareMethods.put("string", "compareString");
		compareMethods.put("date", "compareDate");
		compareMethods.put("bigdecimal", "compareBigDecimal");
	}
	
	//public SingleAttributeComparator(){}
	/**
	 * 构造函数
	 * @param c 要比较的类
	 * @param fieldName 类的某一属性名称
	 * @param isAsc 是根据此属性升序排列 or倒序排列 :true为升序,false为倒序
	 */
	public BasicDataSingleUniversalComparator(Class<?> c, String fieldName, boolean isAsc) 
		throws Exception {
		this.c = c;
		this.fieldName = fieldName;
		field = this.c.getDeclaredField(this.fieldName);
		filedTypeName = field.getType().getSimpleName();
		this.isAsc = isAsc;
		if(this.isAsc) {
			asc = 1;
		} else {
			asc = -1;
		}
	}
	
	@Override
	public int compare(Object o1, Object o2) {
		int result = 0;
//		String fieldType = field.getType().getSimpleName();
		try {
			field.setAccessible(true); //破坏了private,另外一种方案是:调用属性的get方法,但必须保证要有规范的get方法
			Object value1 = field.get(o1);
			Object value2 = field.get(o2);
			result = compareBasicData(value1, value2);
			
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return result;
	}

	/**
	 * 认为null是最小的
	 * @param value1
	 * @param value2
	 * @return
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 */
	private int compareBasicData(Object value1, Object value2) throws Exception {
		int result = 0;
		if((value1 == null && value2 == null)) {
			result = 0;
		} else if(value1 == null) {
			result = -1*asc; //null是最小的,返回1*asc,如果是升序,则1*asc=1,否则1*asc=-1
		} else if(value2 == null) {
			result = 1*asc;
		} else if(value1.equals(value2)) {
			result = 0;
		} else {
			Method method = this.getClass().getDeclaredMethod(compareMethods.get(filedTypeName.toLowerCase()), Object.class, Object.class);
			result = (Integer)method.invoke(this, value1, value2);
		}
		return result*asc;
	}
	
	@SuppressWarnings("unused")
	private int compareBoolean(final Object value1, final Object value2) {
		Boolean v1 = (Boolean)value1;
		Boolean v2 = (Boolean)value2;
		return v1.compareTo(v2);
	}
	@SuppressWarnings("unused")
	private int compareByte(final Object value1, final Object value2) {
		Byte v1 = (Byte)value1;
		Byte v2 = (Byte)value2;
		return v1.compareTo(v2);
	}
	@SuppressWarnings("unused")
	private int compareCharacter(final Object value1, final Object value2) {
		Character v1 = (Character)value1;
		Character v2 = (Character)value2;
		return v1.compareTo(v2);
	}
	@SuppressWarnings("unused")
	private int compareInteger(final Object value1, final Object value2) {
		Integer v1 = (Integer)value1;
		Integer v2 = (Integer)value2;
		return v1.compareTo(v2);
	}
	@SuppressWarnings("unused")
	private int compareLong(final Object value1, final Object value2) {
		Long v1 = (Long)value1;
		Long v2 = (Long)value2;
		return v1.compareTo(v2);
	}
	@SuppressWarnings("unused")
	private int compareFloat(final Object value1, final Object value2) {
		Float v1 = (Float)value1;
		Float v2 = (Float)value2;
		return v1.compareTo(v2);
	}
	@SuppressWarnings("unused")
	private int compareDouble(final Object value1, final Object value2) {
		Double v1 = (Double)value1;
		Double v2 = (Double)value2;
		return v1.compareTo(v2);
	}
	@SuppressWarnings("unused")
	private int compareDate(final Object value1, final Object value2) {
		Date v1 = (Date)value1;
		Date v2 = (Date)value2;
		return v1.compareTo(v2);
	}
	@SuppressWarnings("unused")
	private int compareString(final Object value1, final Object value2) {
		String v1 = (String)value1;
		String v2 = (String)value2;
		return v1.compareTo(v2);
	}
	
	@SuppressWarnings("unused")
	private int compareBigDecimal(final Object value1, final Object value2) {
		BigDecimal v1 = (BigDecimal)value1;
		BigDecimal v2 = (BigDecimal)value2;
		return v1.compareTo(v2);
	}
}

 

使用方法如下:

例如我有一个Airport 机场类,里面有一个属性airportCode(机场三字码),

现在myList存放的是Airport元素列表,希望根据airportCode倒序排列(升序true,倒序false),那么

Collections.sort(myList, new BasicDataSingleUniversalComparator (Airport.class, "airportCode", false));

就搞定了。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值