關于對Java List的通用排序實現
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
};
}</pre>測試用例也給大家提供一個
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;
}
}
}</pre>測試結果如下:
打印排序前結果 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條來自:http://blog.csdn.net/xzknet/article/details/7992403