`
Ivan0513
  • 浏览: 211802 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

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

阅读更多

当我们获得一个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));

就搞定了。

 

 

 

分享到:
评论

相关推荐

    智能电器现状、前景.doc

    随着单片机功能日益完善、传感器技术 、计算机网络和数字通信技术的高速发展,在短短20多年内,智能电器已经从简单的采用 微机控制取代传统机电控制功能的单一封闭式装置,发展到具有比较完整的理论体系和 多学科交叉...

    Python核心编程(第二版).pdf (压缩包分2部分,第二部分)

     8.6.3 用于迭代器类型   8.6.4 range()内建函数   8.6.5 xrange() 内建函数   8.6.6 与序列相关的内建函数   8.7 break语句   8.8 continue语句   8.9 pass语句   8.10 再谈else语句  ...

    Python核心编程(第二版).pdf (压缩包分2部分,第一部分)

     8.6.3 用于迭代器类型   8.6.4 range()内建函数   8.6.5 xrange() 内建函数   8.6.6 与序列相关的内建函数   8.7 break语句   8.8 continue语句   8.9 pass语句   8.10 再谈else语句  ...

    通用Easyui开发框架源码(For Asp.NET)

    如果业务比较单一且相对简单,就可以直接调用或者使用Web Service/Remoting/WCF作为通信框架即可。在实施SOA的过程中,可以自己使用WCF+WF搭建一个小型轻量级的SOA框架,也可以使用诸如Biztalk等软件。 三、注意事项...

    Python核心编程第二版

     8.6.3 用于迭代器类型   8.6.4 range()内建函数   8.6.5 xrange() 内建函数   8.6.6 与序列相关的内建函数   8.7 break语句   8.8 continue语句   8.9 pass语句   8.10 再谈else语句  ...

    Python核心编程第二版(ok)

     8.6.3 用于迭代器类型   8.6.4 range()内建函数   8.6.5 xrange()c内建函数   8.6.6 与序列相关的内建函数   8.7 break语句   8.8 continue语句   8.9 pass语句   8.10 再谈else语句  ...

    电子元器件基础知识大全:IC测试原理解析

    电子元器件基础知识大全:IC测试原理解析 数字通信...通用数字通信系统发射器的简单模块图 先进的数字信号处理和专用应用芯片技术提高了数字系统的集成度。现在一块单一的芯片就集成了从ADC转换到中频调制输出的大部

    数据采集系统实验报告报告.doc

    此地址经译码选通8路模拟输入之一到比较器。START上升沿将逐次逼近寄存器复位。下 降沿启动 A/D转换,之后EOC输出信号变低,指示转换正在进行。直到A/D转换完成,EOC变为高 电平,指示A/D转换结束,结果数据已...

    ADS1015-4通道可编程增益放大器设计,附原理图/PCB/ADS1015源码-电路方案

    本项目是基于ADS1015-4通道12位ADC可编程增益放大器设计,见附原理图/PCB/ADS1015源码。...可编程比较器 该板/芯片使用I2C8位地址,位于0x48-0x4B之间,可选择跳线 ADS1015-4通道可编程增益放大器ADS1015源码截图:

    操作系统:精髓与设计原理(原书第6版)

    第二部分 进程:详细分析进程、多线程、对称多处理(SMP)和微内核,还讨论了单一系 统中的并发机制,重点讲述了互斥和死锁。 第三部分 存储器:全面讲述存储器管理技术,包括虚拟存储器。 第四部分 调度:对多种...

    微型计算机机原理与接口技术习题

    累加器是比较特殊的通用寄存器。它在某些指令执行前,它可以保存一源操作数,还在执行后又用来保存运算结果,另外它一般也用来完成输入/输出指令。而通用寄存器则一般只用来保存参加运算的数据、运算的中间的结果...

    桌美主题下载

    三分屏课件打包加密器软件是由免费网络软件下载站推荐下载的一款专门针对三分屏课件加密打包软件,3分屏课件是远程教育领域比较流行的一种课件形式,音频、视频、ppt同步导航,课件表现形式生动活泼,唯一的缺点是...

    LEAP_CrossoverShop分频器设计教程.pdf

    CrossoverShop比较特殊的功能包括有模拟有源和无源的设计和分析、数字过滤器FIR和IIR设计及分析、结合模拟和数字形式设计、全球通用的优化引擎等等 EnclosureShop提供了预先模拟以及喇叭和箱体特性的模型模拟。其它...

    串口协议的具体介绍.doc

    1. 串行传输:数据通过一个单一的通道进行传输,一次只传输一个数据位。 2. 异步通信:数据传输的速度不固定,根据接收设备的处理能力进行调整。 3. 同步通信:数据传输的速度由定时脉冲控制,传输速度比较稳定。 ...

    Oracle数据库11g各版本介绍及功能比较

    这些版本都使用相同的通用代码库构建,这意味着企业的数据库管理软件可以轻松地从规模较小的单一处理器服务器扩展到多处理器服务器集群,而无需更改一行代码。 标准版 标准版是 Oracle 数据库 11g 的基本版本,...

    基于 AVR 的单片嵌入式系统原理与实践应用

    片内模拟比较器; 内含可编程的,具有独立片内振荡器的看门狗定时器WDT; (5)其它的特点 片内含上电复位电路以及可编程的掉电检测复位电路BOD; 片内含有1M/2M/4M/8M,经过标定的、可校正的RC振荡器,可作为系统...

    wordpress入门到精通教程

    1)文档类型 当我们用dreamweaver新建一下html格式文档时,查看源代码,会发现代码最上部有如下这句话: &lt;!DOCTYPE ...

    基于OMAP架构的智能手持设备设计

     传统的手持设备,如人们较为熟悉的PDA,基本功能均比较简单,主要是管理个人信息,如通讯录、备忘录,以及计算器、录音和辞典等功能。这些功能都是固化的,不能根据用户的要求进行改进,而且在人机接口、多媒体和影音支持...

    双法兰液位计原理与调试.doc

    双法兰液位计在工业中起着非常重要的作用,测量介质比较单一,不能测混合物、结晶等凝聚物块,膜盒是它最重要的部分,化工生产维修时要保护好膜盒,必要时加装膜盒盖子。 一、概述 双法兰液位计由横河和霍尼韦尔两...

Global site tag (gtag.js) - Google Analytics