List的排序大家都会想到实现Comparator接口,但是如果我们需要对list排序是动态,就比较崩溃了,复杂度不言而喻。经过仔细思索,写了一个工具类,使用反射机制实现对list对象的排序功能,专门用于List对象的排序工作。
package xzknet.net.csdn.blog.utils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.BeanUtils;
/**
* List排序工具
*
* @author Ken.xu(mailto:xzknet@gmail.com)
* @version 1.0 Copyright 2012-9-18 下午04:37:17
* @param <T>
*/
public class ListSortUtil<T> {
private Map<Method, Direction> sortField = new LinkedHashMap<Method, Direction>();
private Map<String, Method> propertyMethodMap = null;
// Method[] methods
public ListSortUtil(final Class clazz) {
PropertyDescriptor[] propertyDescriptor = BeanUtils.getPropertyDescriptors(clazz);
Map<String, Method> propertyMethodMap = new HashMap<String, Method>();
for (PropertyDescriptor pd : propertyDescriptor) {
String key = pd.getName();
Method value = pd.getReadMethod();
propertyMethodMap.put(key, value);
}
this.propertyMethodMap = propertyMethodMap;
}
public void clear() {
sortField.clear();
}
/**
* 增加一个降序
*
* @param fieldName
* @throws NoSuchMethodException
* @author Ken_xu
*/
public void addDesc(String fieldName) throws NoSuchMethodException {
addFieldMethod(fieldName, Direction.DESC);
}
/**
* 增加一个升序
*
* @param fieldName
* @throws NoSuchMethodException
* @author Ken_xu
*/
public void addAsc(String fieldName) throws NoSuchMethodException {
addFieldMethod(fieldName, Direction.ASC);
}
/**
* 增加一个字段排序模式
*
* @param fieldName
* @param direction
* @throws NoSuchMethodException
* @author Ken_xu
*/
private void addFieldMethod(String fieldName, Direction direction) throws NoSuchMethodException {
Method method = propertyMethodMap.get(fieldName);
if (method == null) {
throw new NoSuchMethodException(fieldName);
} else {
sortField.put(method, direction);
}
}
public List<T> sortList(List<T> list) {
if (sortField.isEmpty() == false) {
Comparator<T> comparator = new Comparator<T>() {
public int compare(T o1, T o2) {
int flag = 0;
for (Map.Entry<Method, Direction> entry : sortField.entrySet()) {
Method method = entry.getKey();
Direction direction = entry.getValue();
if (direction == Direction.ASC) {
// DESC:降序
flag = this.compareByFlag(method, o1, o2);
} else {
// ASC:升序
flag = this.compareByFlag(method, o2, o1);
}
if (flag != 0) {
break;
}
}
if (flag > 0) {
flag = 1;
} else if (flag < 0) {
flag = -1;
}
return flag;
}
/**
* 如果t1大于t2:1<br>
* t1等于t2:0<br>
* t1小于t2:-1
*
* @param flag
* @param t1
* @param t2
* @return
* @author Ken_xu
*/
private int compareByFlag(Method method, T t1, T t2) {
int flag = 0;
try {
String methodReturn1 = method.invoke(t1).toString();
String methodReturn2 = method.invoke(t2).toString();
flag = methodReturn1.compareTo(methodReturn2);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return flag;
}
};
Collections.sort(list, comparator);
}
return list;
}
/**
* 排序方式:
* <p>
* ASC:升序<br/> DESC:降序
*
*/
enum Direction {
ASC, DESC
};
}
测试用例也给大家提供一个
package xzknet.net.csdn.blog.utils;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
public class ListSortUtilTest extends TestCase {
private List<TestUser> list = null;
/**
* 打印清单
*
* @author Ken_xu
*/
private void printListEg() {
List<TestUser> TestUserList = new ArrayList<TestUser>();
for (int i = 0, maxIdx = list.size(); i < maxIdx; i++) {
TestUser tm = list.get(i);
String showTxt = String.format("%d)\t modelName=%s;\t\t extendsModel=%s;", i, tm.getModelName(), tm.getExtendsModels());
System.out.println(showTxt);
if (i == (maxIdx - 1)) {
showTxt = String.format("...................总共:%d条", list.size());
System.out.println(showTxt);
}
TestUserList.add(tm);
}
list = TestUserList;
}
/**
* 初始化测试用例
*/
protected void setUp() throws Exception {
super.setUp();
List<TestUser> TestUserList = new ArrayList<TestUser>();
long rowNum = 0l;
for (int i = 0; i < 10; i++) {
TestUser tm = new TestUser();
if (i % 2 == 0) {
// 每两个对象的modelName相同
rowNum = Math.round(Math.random() * 100);
}
tm.setModelName("AAA_TEST_" + rowNum);
tm.setExtendsModels("BBBBBBB" + i);
TestUserList.add(tm);
}
list = TestUserList;
}
/**
* 测试排序
*
* @author Ken_xu
*/
public void testSort() {
ListSortUtil<TestUser> sortUtil = new ListSortUtil(TestUser.class);
try {
sortUtil.addDesc("modelName");
sortUtil.addAsc("extendsModels");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
System.out.println("打印排序前结果");
printListEg();
sortUtil.sortList(list);
System.out.println("打印排序后结果");
printListEg();
}
class TestUser {
String modelName, extendsModels;
public String getModelName() {
return modelName;
}
public void setModelName(String modelName) {
this.modelName = modelName;
}
public String getExtendsModels() {
return extendsModels;
}
public void setExtendsModels(String extendsModels) {
this.extendsModels = extendsModels;
}
}
}
测试结果如下:
打印排序前结果
0) modelName=AAA_TEST_48; extendsModel=BBBBBBB0;
1) modelName=AAA_TEST_48; extendsModel=BBBBBBB1;
2) modelName=AAA_TEST_29; extendsModel=BBBBBBB2;
3) modelName=AAA_TEST_29; extendsModel=BBBBBBB3;
4) modelName=AAA_TEST_1; extendsModel=BBBBBBB4;
5) modelName=AAA_TEST_1; extendsModel=BBBBBBB5;
6) modelName=AAA_TEST_63; extendsModel=BBBBBBB6;
7) modelName=AAA_TEST_63; extendsModel=BBBBBBB7;
8) modelName=AAA_TEST_73; extendsModel=BBBBBBB8;
9) modelName=AAA_TEST_73; extendsModel=BBBBBBB9;
...................总共:10条
打印排序后结果
0) modelName=AAA_TEST_73; extendsModel=BBBBBBB8;
1) modelName=AAA_TEST_73; extendsModel=BBBBBBB9;
2) modelName=AAA_TEST_63; extendsModel=BBBBBBB6;
3) modelName=AAA_TEST_63; extendsModel=BBBBBBB7;
4) modelName=AAA_TEST_48; extendsModel=BBBBBBB0;
5) modelName=AAA_TEST_48; extendsModel=BBBBBBB1;
6) modelName=AAA_TEST_29; extendsModel=BBBBBBB2;
7) modelName=AAA_TEST_29; extendsModel=BBBBBBB3;
8) modelName=AAA_TEST_1; extendsModel=BBBBBBB4;
9) modelName=AAA_TEST_1; extendsModel=BBBBBBB5;
...................总共:10条