List對象排序通用方法

List對象排序通用方法

 

在數據庫中查出來的列表中,往往需要對不同的字段重新排序,一般的做法都是使用排序的字段,重新到數據庫中查詢。如果不到數據庫查詢,直接在第一次查出來的list中排序,無疑會提高系統的性能。

只要把第一次查出來的結果存放在session中,就可以對list重新排序了。一般對list排序可以使用Collections.sort(list),但如果list中包含是一個對象的話,這種方法還是行不通的。如果有下面這個對象:

複製代碼
//UserInfo.java
package test;

import java.text.SimpleDateFormat;


public class UserInfo implements java.io.Serializable{
    
    private java.lang.Integer userId;
    private java.lang.String username;
    private java.util.Date birthDate;    
    private java.lang.Integer age;

    private SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
    
    public UserInfo(){
    }

    public UserInfo(
        java.lang.Integer userId,
        java.lang.String username,
        java.util.Date birthDate,
        java.lang.Integer age
    ){
        this.userId = userId;
        this.username = username;
        this.birthDate = birthDate;
        this.age = age;
    }

    public void setUserId(java.lang.Integer value) {
        this.userId = value;
    }
    
    public java.lang.Integer getUserId() {
        return this.userId;
    }
    public void setUsername(java.lang.String value) {
        this.username = value;
    }
    
    public java.lang.String getUsername() {
        return this.username;
    }
    
    public void setBirthDate(java.util.Date value) {
        this.birthDate = value;
    }
    
    public java.util.Date getBirthDate() {
        return this.birthDate;
    }
    
    public void setBirthDatestr(String value) throws Exception{
        setBirthDate(formater.parse(value));
    }
    
    public java.lang.String getBirthDatestr() {
        return formater.format(getBirthDate());
    }
    
    public void setAge(java.lang.Integer value) {
        this.age = value;
    }
    
    public java.lang.Integer getAge() {
        return this.age;
    }

    public String toString() {
        return new StringBuffer()
            .append(getUserId())
            .append("; "+getUsername())
            .append("; "+getBirthDatestr())
            .append("; "+getAge())
            .toString();
    }
複製代碼

這是一個簡單的數據對象,現在要對userId排序,那麼用上述的方法必須要用到如下所示類似的代碼:

 

Collections.sort(list, new Comparator() {
                                public int compare(Object a, Object b) {
                                  int one = ((Order)a).getUserId ();
                                  int two = ((Order)b).getUserId (); 
                                  return one- two ; 
                                }
                             });

那麼要實現對UserInfo列表各字段排序,是不是每個字段都寫一段如上所示的代碼呢?那當然不是我們所需要的結果。寫程序要寫得越來越精練,不能越寫越冗餘。能不能寫一個通用的方法呢?答案是肯定的,但首先必須能解決下面三個問題:

 

1.  可以使用泛型;

2.  能夠使用通用的比較方法,比如compareTo

3.  有沒有類似泛型、泛型方法那樣的泛方法?

第1個問題可以解決,第2個問題難度也不是很大,因爲Java所有的類型都繼承於Object,都有一個ToString的方法,暫且可以把所有類型轉換成String,然後用compareTo作比較。第3個問題,日前還沒有我們需要的泛方法。不過我們可以變通一下,用getMethod和invoke動態的取出方法出來。完成代碼如下:

複製代碼
//SortList.java
package test;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
/**
* @author jardot
* @version 1.0
* 通用排序
*/
public class SortList<E>{    
    public void Sort(List<E> list, final String method, final String sort){
        Collections.sort(list, new Comparator() {            
            public int compare(Object a, Object b) {
                int ret = 0;
                try{
                    Method m1 = ((E)a).getClass().getMethod(method, null);
                    Method m2 = ((E)b).getClass().getMethod(method, null);
                    if(sort != null && "desc".equals(sort))//倒序
                        ret = m2.invoke(((E)b), null).toString().compareTo(m1.invoke(((E)a), null).toString());    
                    else//正序
                        ret = m1.invoke(((E)a), null).toString().compareTo(m2.invoke(((E)b), null).toString());
                }catch(NoSuchMethodException ne){
                    System.out.println(ne);
                }catch(IllegalAccessException ie){
                    System.out.println(ie);
                }catch(InvocationTargetException it){
                    System.out.println(it);
                }
                return ret;
            }
         });
    }
}
複製代碼

 

成功了!上面的代碼沒有用到具體的對象和類型,已經具有通用性了,我們用了一個泛型E,如果我們要對UserInfouserId排序的話,可以把方法名用字符串的形式用參數傳進去:例如“getUserId”。可以使用下面的代碼測試一下:

複製代碼
//Test.java
package test;

import java.util.ArrayList;
import java.util.List;
import java.text.SimpleDateFormat;

public class Test {

    public static void main(String[] args)throws Exception{
        List<UserInfo> list = new ArrayList<UserInfo>();
        
        SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
        
        list.add(new UserInfo(3,"b",formater.parse("1980-12-01"),11));
        list.add(new UserInfo(1,"c",formater.parse("1980-10-01"),30));
        list.add(new UserInfo(2,"a",formater.parse("1973-10-01"),11));
                    
        System.out.println("-------原來序列-------------------");
        for(UserInfo user : list){
            System.out.println(user.toString());
        }        
        
        //調用排序通用類
        SortList<UserInfo> sortList = new SortList<UserInfo>();
        
        //按userId排序
        sortList.Sort(list, "getUserId", "desc");
        System.out.println("--------按userId倒序------------------");
        for(UserInfo user : list){
            System.out.println(user.toString());
        }
        
        //按username排序
        sortList.Sort(list, "getUsername", null);
        System.out.println("---------按username排序-----------------");        
        for(UserInfo user : list){
            System.out.println(user.toString());
        }
        
        //按birthDate排序
        sortList.Sort(list, "getBirthDatestr", null);
        System.out.println("---------按birthDate排序-----------------");        
        for(UserInfo user : list){
            System.out.println(user.toString());
        }
        
    }
    
}
複製代碼

運行結果如下:

 

-------原來序列-------------------

3; b; 1980-12-01; 11

1; c; 1980-10-01; 30

2; a; 1973-10-01; 11

--------按userId倒序------------------

3; b; 1980-12-01; 11

2; a; 1973-10-01; 11

1; c; 1980-10-01; 30

---------按username排序-----------------

2; a; 1973-10-01; 11

3; b; 1980-12-01; 11

1; c; 1980-10-01; 30

---------按birthDate排序-----------------

2; a; 1973-10-01; 11

1; c; 1980-10-01; 30

3; b; 1980-12-01; 11

注意:日期的排序是先通過格式轉換的,再來排序的,否則將不能有正確的結果。

發佈了51 篇原創文章 · 獲贊 13 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章