public class MultiCompare implements Comparator<Object> {
int sort = 1;// sort 1正序 -1 倒序 filed 多字段排序
String[] fileds;
boolean flag2 = false;//标识是否是第二种排序,即多字段的排序方向不全一致
//如果多个字段的排序方向一致,可用此方式
public MultiCompare(int sort, String... fields) {
this.sort = sort == -1 ? -1 : 1;
this.fileds = fields;
}
//如果多个字段的排序方向不全一致,可用此方式,格式固定为:field1_1、field2_-1
public MultiCompare(String... fields){
this.sort = 0;
this.fileds = fields;
}
//重写compare方法
@Override
public int compare(Object o1, Object o2) {
int result = 0;
for (String field : fileds) {
try {
if(sort == 0 || flag2){
flag2 = true;
String[] ss = field.split("_");
if(ss.length > 1){
sort = Integer.parseInt(ss[1]);
field = ss[0];
}
}
Object value1 = invokeMethod(field, o1);
Object value2 = invokeMethod(field, o2);
if(value1 == null)value1 = "";
if(value2 == null)value2 = "";
String v1 = String.valueOf(value1.toString());
String v2 = String.valueOf(value2.toString());
if (v1.equals(v2))
continue;
if (sort == 1) {
return v1.compareTo(v2);
} else if (sort == -1) {
return v2.compareTo(v1);
} else {
continue;
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
return result;
}
//根据属性名,获取对应的get方法的值
private static Object invokeMethod(String propertiesName, Object object) {
try {
if (object == null)
return null;
if (!propertiesName.contains(".")) {
String methodName = "get" + getMethodName(propertiesName);
Method method = object.getClass().getMethod(methodName);
return method.invoke(object);
}
String methodName = "get"
+ getMethodName(propertiesName.substring(0,
propertiesName.indexOf(".")));
Method method = object.getClass().getMethod(methodName);
return invokeMethod(
propertiesName.substring(propertiesName.indexOf(".") + 1),
method.invoke(object));
} catch (Exception e) {
return null;
}
}
//将字段名的首字母转为大写
private static String getMethodName(String fieldName) {
byte[] items = fieldName.getBytes();
items[0] = (byte) ((char) items[0] - 'a' + 'A');
return new String(items);
}
}
使用方式如下:
public static void main(String args[]) {
Collections.sort(list,new MultiCompare(1, "field1", "field2"));
Collections.sort(list,new MultiCompare("field1_1", "field2_-1"));
}