关于对Java List的通用排序实现

jopen 10年前

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