关于对Java List的通用排序实现
jopen
12年前
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条来自:http://blog.csdn.net/xzknet/article/details/7992403