關于對Java List的通用排序實現

jopen 13年前發布 | 42K 次閱讀 Java Java開發

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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!