当我们获得一个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));
就搞定了。
分享到:
相关推荐
这表明LM559可能是一个特定型号,但相关资料和特性与LM339系列比较器是通用的,或者LM559可能是LM339系列中的一个型号,尽管在通用型号列表中未明确列出。 通过以上知识点,可以看出LM339系列比较器是非常适合需要...
其基本原理是用单一的I/O端口,执行1位的数模转换,以比较器的输出作反馈,来维持Vout与Vin相等。该电路方案可以实现在MSP430F1121单片机上实现高精度A/D转换。 在该电路方案中,产生1位DAC的电路为一路通用I/O口、...
集中式是指由单一主机执行爬取任务,这种架构中,由于单一主机的性能与计算资源的限制,比较适合执行任务量较小的爬取任务,如面向某一主题的网页抓取。而通用爬虫的任务量通常很大,集中式的架构不能满足效率和时间...
#### 电动机控制专用微处理器:8XC196Mx系列 - **制造商**: Intel公司 - **系列型号**: 80C196MC/80C196MD/80C196MH等 - **类型**: 16位微处理器 - **应用领域**: 三相电动机变频调速控制 - **特点**: 高性能CMOS...
这些设备由四个独立的单或双电源电压比较器组成,集成在单一的单晶硅基板上。它们能够处理包括接地在内的宽范围输入电压,并且由于低功耗特性,非常适合电池供电的应用场景。此外,它们还被设计为可以直接与TTL和...
- 迭代器:遍历容器中的元素,执行各种操作。 - 预定义算法:如排序(sort)、查找(find)、交换(swap)等。 - 功能对象:如函数对象(functors)、比较函数对象、适配器等。 6. **输入/输出流**: - 文件流...
- `static final`修饰的基本类型标识符全大写,表示它们是编译时常量。 - Java包名全小写,即使包含多个单词,如`com.example.myapp`。 2. **通用方法**: - 创建通用类时,应提供`equals()`, `hashCode()`, `...
- **函数对象(functors)**:自定义行为,如比较器、变换器等。 5. **异常处理** - **异常的抛出与捕获**:理解try、catch和throw关键字的使用。 - **异常安全**:编写能够正确处理异常的代码,保证资源的正确...
10. 比较器: - 提供比较器模块,用于信号分析和转换。 11. 封装选项: - 提供38脚DA薄型小型外尺寸封装(TSSOP)和48脚PT薄型方形扁平封装(LQFP)。 12. 电源与功耗: - 设计用于低功耗应用,支持小引脚封装,...
- **比较器**:如果TreeSet集合未传入比较器,则集合中的元素需实现Comparable接口,以便进行排序。 #### 题目16:数据模型分类 - **知识点**:本题考查数据模型的分类。 - **树形结构**:层次模型使用树形结构...
- 迭代器:理解迭代器的工作原理,如何遍历容器中的元素。 - 预算器(algorithms):如排序、查找、变换等常用算法。 - 函数对象(functors)和适配器:如比较函数、谓词、函数指针转换等。 8. **C++11及更高...
1. 变量与数据类型:C++支持基本数据类型(如int、float、char)以及构造数据类型(如数组、结构体)。理解变量声明、初始化和作用域规则至关重要。 2. 运算符:包括算术运算符、比较运算符、逻辑运算符、赋值运算符...
我们可以创建一个实现了`IComparer<Student>`的类,然后在排序时传递这个比较器: ```csharp public class StudentNameComparer : IComparer { public int Compare(Student x, Student y) { return x.Name....
- **变量和数据类型**:理解基本数据类型(如int, float, double, char等),以及如何声明和初始化变量。 - **运算符**:熟悉各种运算符,如算术运算符、比较运算符、逻辑运算符、赋值运算符等。 - **控制结构**...
当将iDrive智能伺服驱动器与传统的通用伺服驱动器进行比较时,差异显而易见: 1. 通用伺服驱动器通常需要外部运动控制卡或PLC发送脉冲信号,容易发生丢失脉冲现象。而iDrive采用网络通信,提高了信号传递的可靠性。...
- **数据类型**:包括基本类型(整型、浮点型等)和复合类型(指针、数组等)。 - **算术运算符**:支持基本的数学运算。 - **关系运算符**:用于比较操作,如 `、`>` 等。 - **逻辑运算符**:`&&`、`||` 和 `!`。 -...