1. 程式人生 > >使用map操作物件排序,根據物件欄位排序

使用map操作物件排序,根據物件欄位排序

map是一個由鍵值對資料組成的集合。在某個專案中,前端顯示的資料量不大,於是採用map進行顯示。但是後來才發現,這樣並不是最簡單的處理方式,但是由於一開始沒考慮好,一路坑到底。把對資料庫的操作轉成在map身上,如果只是用於學習,可以借鑑,如果是要在專案中進行操作的話,可能會偏複雜,特別是分頁操作。

現在描述一下我們的需求:

一 :假設一個物件有三個欄位用來儲存三個名稱,現在要進行排序顯示,第三個名詞根據第二個名稱排序,第二個名稱根據第一個名稱排序。

     1:從資料取出資料,存放在Map<String, **>中,**是代表物件,這邊用Object代替。key可以根據物件id儲存,注意:key不能重複,否則資料會出現缺漏。

現在前端要顯示,呼叫儲存的map資料,所以我們需要對資料進行排序

    public static Map<String, Object> getSortMap() {
        Map<String, Object> tempMap = new LinkedHashMap<String, Object>();
        List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(map.entrySet()

);//這裡的map是資料庫查找出來的資料
        Collections.sort(list,new MyComparator()); //排序操作
        Iterator<Map.Entry<String, Object>> i = list.iterator();
        while (i.hasNext()) {
          Map.Entry<String, Object> entry = i.next();
          tempMap.put(entry.getKey(),entry.getValue());
        }
        return tempMap;
    }

排序類:


public class MyComparator implements Comparator<Map.Entry<String, Object>> {

    /**
     * //:根據父級排序,再根據本身的排序值排序
     */
    /*@Override
    public int compare(Entry<String, Object> o1, Entry<String, Object> o2) {
        Object h1=o1.getValue();
        Object h2=o2.getValue();
        if ((h1.getName1().compareTo(h2.getName2()))>0) {//先根據第一個名稱排序
            return 1;
        } else     if ((h1.getName1().compareTo(h2.getName1()))==0) {
            if ((h1.getName2().compareTo(h2.getName2()))>0) {//第一個名稱相同按第二個名稱排序
                return 1;
            }else if ((h1.getName2().compareTo(h2.getName2()))==0) {
                if ((h1.getName3().compareTo(h2.getName3()))==0) {//第二個名稱相同按第三個名稱排序
                    return 1;
                }else if(Integer.parseInt(h1.getDisplayorder())==Integer.parseInt(h2.getDisplayorder())){
                    return 0;
                }else{
                    return -1;
                }
            }else{
                return 0;
            }
        } else
            return -1;
    }
}

二:現在資料在前端可以顯示了,但是呢,點選欄位的時候要根據這個欄位排序。針對不同框架,前端傳過來的資料可能略不同,這邊是傳“欄位名+空格+排序方式(ASC/DESC)”,比如要根據object的id進行排序,點選的時候會傳id desc或者id asc過來。

1:在object穿件一個排序欄位order

現在在controller需要這樣處理

String orderBy=page.getOrder();//框架封裝自動傳輸的資料
object.order=orderBy;//賦值

2:在相同的getSortMap()進行操作

public static Map<String, Object> getSortMap() {
        Map<String, Object> tempMap = new LinkedHashMap<String, Object>();
        List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(map.entrySet());//這裡的map是資料庫查找出來的資料
       if(StringUtils.isNotEmpty(Object.order)){//欄位排序操作返回
              Collections.sort(list,new MyComparator2(getOrder()));//另一個排序介面
        }else{//正常顯示的排序返回
            Collections.sort(list,new MyComparator());
        }
        Iterator<Map.Entry<String, Object>> i = list.iterator();
        while (i.hasNext()) {
          Map.Entry<String, Object> entry = i.next();
          tempMap.put(entry.getKey(),entry.getValue());
        }
        return tempMap;
    }

//這邊要根據欄位排序,我們的思路是通過反射遍歷object屬性,如果前端傳過來的屬性名稱跟object欄位名稱一樣,則根據這個欄位進行排序

public class MyComparator2 implements Comparator<Map.Entry<String, Object>> {
    
    private String orderBy;
    
    public Level2Comparator(String orderBy) {
        this.orderBy=orderBy;
    }
    
    /**
     * 列表排序,根據屬性值排序
     */
    @Override
    public int compare(Entry<String, Object> o1, Entry<String, Object> o2) {
        Object h1=o1.getValue();
        Object h2=o2.getValue();
        if(StringUtils.isNotEmpty(orderBy)){

            String[] fileNames=orderBy.split(" ");
            String name=fileNames[0];//屬性名稱
            String rule=fileNames[1];//規則.升降
            Field[] fs = HkCategory.class.getDeclaredFields();
            for(int i = 0 ; i < fs.length; i++){  
                 Field f = fs[i];
                 f.setAccessible(true); //設定些屬性是可以訪問的  
                 String fileName=f.getName();//屬性名稱
                 try {

                     if(name.indexOf(".")>0){//特殊欄位處理比如"level1.name"
                         String name2=name.substring(name.indexOf(".")+1,name.length());
                         name=name.substring(0, name.indexOf("."));
                     }
                     if(fileName.equals(name)){
                         if("level1".equals(name)||"level2".equals(name)){
                             LevelCategory level1=null;
                             LevelCategory level2=null;
                             if("level1".equals(name)){
                                 level1=h1.getLevel1();
                                 level2=h2.getLevel1();
                             }
                             if("level2".equals(name)){
                                 level1=h1.getLevel2();
                                 level2=h2.getLevel2();                       
                             }
                             if((level1.getName().compareTo(level2.getName()))>0){
                                 if("ASC".equals(rule)){
                                     return 1;
                                 }else{
                                     return -1;
                                 }
                                }else   if((level1.getName().compareTo(level2.getName()))==0){
                                    return 0;
                                }else{
                                     if("ASC".equals(rule)){
                                         return -1;
                                     }else{
                                         return 1;
                                     }
                                }
                         }
                        
                         String UpFirstOrderBy=name.substring(0, 1).toUpperCase();
                         String UpOrderBy=UpFirstOrderBy+name.substring(1, name.length());
                         Method m2 = HkCategory.class.getMethod("get"+UpOrderBy);//呼叫get方法
                         Object obj1=m2.invoke(h1);//獲取屬屬性值
                         Object obj2=m2.invoke(h2);;//獲取屬屬性值

                         String fileType = f.getType().getSimpleName().toLowerCase();//得到此屬性的型別
                         if("integer".equals(fileType)){//srtring,date,integer不同的資料型別,排序操作不一樣
                             Integer a1=(Integer) obj1;
                             Integer a2=(Integer) obj2;
                             if(a1>a2){
                                 if("ASC".equals(rule)){
                                     return 1;
                                 }else{
                                     return -1;
                                 }    
                                 }else  if(a1==a2){
                                    return 0;
                                }else{
                                     if("ASC".equals(rule)){
                                         return -1;
                                     }else{
                                         return 1;
                                     }
                                }
                            }
                         if("date".equals(fileType)){
                                Date date1=(Date) obj1;
                                Date date2=(Date) obj2;
                                if(date1.getTime()<date2.getTime()){
                                 if("ASC".equals(rule)){
                                     return 1;
                                 }else{
                                     return -1;
                                 }
                                }else  if(date1.getTime()==date2.getTime()){
                                    return 0;
                                }else{
                                     if("ASC".equals(rule)){
                                         return -1;
                                     }else{
                                         return 1;
                                     }
                                }
                            }
                         if("string".equals(fileType)){
                             if("displayorder".equals(fileName)){//數值排序
                                 Integer a1=Integer.parseInt(obj1.toString());
                                 Integer a2=Integer.parseInt(obj2.toString());
                                 if(a1>a2){
                                     if("ASC".equals(rule)){
                                         return 1;
                                     }else{
                                         return -1;
                                     }    
                                     }else  if(a1==a2){
                                        return 0;
                                    }else{
                                         if("ASC".equals(rule)){
                                             return -1;
                                         }else{
                                             return 1;
                                         }
                                    }
                             }else{
                             if((obj1.toString().compareTo(obj2.toString()))>0){
                                 if("ASC".equals(rule)){
                                     return 1;
                                 }else{
                                     return -1;
                                 }
                                }else  if((obj1.toString().compareTo(obj2.toString()))==0){
                                    return 0;
                                }else{
                                     if("ASC".equals(rule)){
                                         return -1;
                                     }else{
                                         return 1;
                                     }
                                }
                            }
                         }
                     }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return 0;
    }
}

綜上:已經完成map的資料顯示,排序操作。如果還有進行分頁,那會繼續麻煩下去,如果是使用資料操作的話,排序可能只要一條sql,所以這個坑就到此為止吧。。。。

希望對你學習map有所幫助。