数组或者集合中存有对象,经常需要对其中的数据进行排序,在java中,Collections和Arrays类中封装了sort方法,实现了对一个数组或者集合的排序。
基于上面的条件,通过配置Comparator的方法,可以实现按照自己需要的条件排序对象信息。
这里完成的是基于java的九个基本类型的比较器,因为基本类型已经实现了Comparable接口,所以实现起来也很方便。其中,对异常的处理并不是很完善,有兴趣的朋友自己去完善这部分代码吧。
// 便捷之处和效率问题
// 由于是采用反射获取对象中的基本类型值,返回值为包装类型
// 包装类型实现了comparable接口,所以你可以获取它的compareTo方法
public abstract class GenericComparator<T> implements Comparator<T> {
public static final boolean ASC = true;
public static final boolean DESC = false;
private static final Class<?>[] BASE_CLASSES = { Integer.class,
String.class, Double.class, Float.class, Boolean.class,
Character.class, Long.class, Short.class, Byte.class };
private Class<T> clz;
private boolean order = ASC;
private String property;
private String compareProperty;
private Method compareMethod;
public GenericComparator(String property) throws Exception {
// 加载泛型类型
@SuppressWarnings("unchecked")
Class<T> temp = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
clz = temp;
// 设置property属性
property(property);
}
public GenericComparator<T> order(boolean order) {
this.order = order;
return this;
}
public GenericComparator<T> property(String property) throws Exception {
this.property = property;
try {
init(); // 进行初始化操作
} catch (Exception e) {
e.printStackTrace();
throw e;
}
return this;
}
@Override
public int compare(T t1, T t2) {
Object ov1 = null;
Object ov2 = null;
int result = 0;
try {
ov1 = value(t1);
ov2 = value(t2);
result = (Integer) compareMethod.invoke(ov1, ov2);
} catch (Exception e) {
e.printStackTrace();
System.exit(0); // 出现问题,退出
}
return order ? result : -result;
}
// 初始化比较参数
private void init() throws SecurityException, NoSuchFieldException,
NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InstantiationException {
if (compareProperty != property) {
compareProperty = property;
compareMethod = method();
}
}
// 获得比较对象中的compareTo方法
private Method method() throws SecurityException, NoSuchFieldException,
NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InstantiationException {
Object o = value(clz.newInstance());
Class<?> v = null;
if (o != null) { // base type has the value
v = o.getClass();
} else { // package type, checked the class in the BASE_CLASSES
Field f = clz.getDeclaredField(property);
v = f.getType();
}
if (!contains(v)) {
throw new NoSuchMethodException(
"the class you used is not based type.");
}
return v.getMethod("compareTo", v);
}
// 获取对象的待比较的值
private Object value(T o) throws SecurityException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException {
Field f = o.getClass().getDeclaredField(property);
if (!f.isAccessible()) {
f.setAccessible(true);
}
return f.get(o);
}
// 验证是否为有效的数据类型
private boolean contains(Class<?> c) {
for (Class<?> cc : BASE_CLASSES) {
if (cc.equals(c)) {
return true;
}
}
return false;
}
}
细心的朋友已经发现了,我上面的这段代码,是一个abstract类,其原因在于:
在构造器中,通过getGenericSuperclass获取它的父类信息以获得它的泛型信息。