java 按list對象多個字段排序

Java List中的數據如何根據對象的某一個或多個字段排序引出Comparable和comparator的使用
     

第一節  對於引入題目的探討
首先把引入題目表述的清楚一些,在一個List中存儲的是一些對象實例,而對象實例包含多個屬性字段,我們要根據對象的某個或者多個屬性來對List進行排序。
假設List中存儲的都是Student類的實例,Student類包含name、gender、id屬性。首先根據Student實例中的name屬性排序,如果兩個名字相同,就再根據id屬性排序。
Student類源碼如下:
[java] 

<strong>package chapter1; 
  
public class Student { 
    private String name; 
    private String gender; 
    private int id; 
    
    public String getName() { 
        return name; 
    } 
    
    public void setName(String name) { 
        this.name = name; 
    } 
    
    public String getGender() { 
        return gender; 
    } 
    
    public void setGender(String gender) { 
        this.gender = gender; 
    } 
    
    public int getId() { 
        return id; 
    } 
    
    public void setId(int id) { 
        this.id = id; 
    } 
}</strong> 
          假設有三個學生:

                                     姓名       性別        ID
                                     宋超       男          100120
                                     伍星       男          100121
                                     宋超       女          100122
            把這三個學生存儲在List裏面,要求首先按照姓名進行排序,如果姓名相同就按照ID排序。
 
1.1.1第一種實現方式:使用Comparable接口;
          使用這種方式時,Student類必須繼承這個接口,並且實現compareTo方法。並且compareTo方法是這個接口的唯一方法。需要注意到一點,在《Effective Java》第十二條中,提供了一個通用的寫法,也就是在類繼承的Comparable接口的時候,利用泛型指明能比較的類型。把Student類改寫如下:
              
[java] 


package chapter1; 
  
public classStudent implementsComparable<Student>{ 
    private String name; 
    private String gender; 
    private int id; 
    
    public String getName() { 
        return name; 
    } 
    
    public void setName(String name) { 
        this.name = name; 
    } 
    
    public String getGender() { 
        return gender; 
    } 
    
    public void setGender(Stringgender) { 
        this.gender = gender; 
    } 
    
    public int getId() { 
        return id; 
    } 
    
    public void setId(int id) { 
        this.id = id; 
    } 
  
    @Override 
    public int compareTo(Student arg0){ 
        //String、Integer、Double、Float等類型都實現有compareTo方法 
        if(this.name.compareTo(arg0.name) == 0) { 
            return Integer.valueOf(id).compareTo(Integer.valueOf(arg0.id)); 
        }else{ 
            return this.name.compareTo(arg0.name); 
        } 
    } 


 
在《Effective Java》中對於compareTo方法有以下幾點提示:
·自反性
·傳遞性
·對稱性
·最好和equals方法值相同
 
那麼,在客戶端調用的時候,直接寫如下代碼:

[java] 


package chapter1; 
  
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 
  
public class ClientInterface { 
                   publicstatic void main(String[] args) { 
                            
                            Studentsongchao = new Student(); 
                            songchao.setGender("Man"); 
                            songchao.setId(100150); 
                            songchao.setName("SongChao"); 
                            
                            Studentwuxing = new Student(); 
                            wuxing.setGender("Man"); 
                            wuxing.setId(100121); 
                            wuxing.setName("WuXing"); 
                            
                            Studentsongchao2 = new Student(); 
                            songchao2.setGender("Women"); 
                            songchao2.setId(100130); 
                            songchao2.setName("SongChao"); 
                            
                            List<Student>students = new ArrayList<Student>(); 
                            students.add(songchao); 
                            students.add(wuxing); 
                            students.add(songchao2); 
                            for(Studentstudent : students) { 
                                     System.out.println("Name  " + student.getName() + " ID  " + student.getId()); 
                            } 
                            
                            System.out.println(); 
                            
                            Collections.sort(students); 
                            for(Studentstudent : students) { 
                                     System.out.println("Name  " + student.getName() + " ID  " + student.getId()); 
                            } 
                   } 
                   

 

 
輸出結果如下:

[java] 


Name  SongChao ID  100150 
Name  WuXing ID  100121 
Name  SongChao ID  100130 
  
Name  SongChao ID  100130 
Name  SongChao ID  100150 
Name  WuXing ID 100121 

 

 
1.1.2另外一種方式:直接使用比較器comparator
 
         直接使用比較器的情況下,Student類不必繼承Comparable接口,當然也不必實現compareTo方法。
         直接看調用代碼,但是注意一點,這裏的Student類沒有繼承Comparable接口。
         直接在上面的客戶端代碼中,把Collections.sort方法替換爲:

[java]


Collections.sort(students, newComparator<Student>() { 
  
            @Override 
            public int compare(Student arg0,Student arg1) { 
                if(arg0.getName().compareTo(arg1.getName())== 0) { 
                    return Integer.valueOf(arg0.getId()).compareTo(Integer.valueOf(arg1.getId())); 
                } else { 
                    returnarg0.getName().compareTo(arg1.getName()); 
                } 
            } 
            
        }); 

 

 
輸出結果和第一種方式相同。
還有一個注意點,那就是排序的順序,是按照由小到大還是由大到小。上面那種方式顯然是從小到大排序,那麼如何從大到小排序?只要改變參數順序即可:
  
[java] 


Collections.sort(students,newComparator<Student>() { 
 
           @Override 
           public int compare(Student arg0,Student arg1) { 
               if(arg1.getName().compareTo(arg0.getName()) == 0) { 
                   return Integer.valueOf(arg1.getId()).compareTo(Integer.valueOf(arg0.getId())); 
               }else{ 
                   return arg1.getName().compareTo(arg0.getName()); 
               } 
           } 
           
       }); 


 
以上是對於sort方法的小總結,Arrays中的sort方法類似。
 
第二節  Collections與Arrays概念分析
1.2.1 Collection和Collections的區別
     Collection是java.util下的接口,是各種集合結構的父接口。繼承它的接口主要有Set和List。
     Collections是java.util下的專用靜態類,包含有各種有關集合操作的靜態方法。提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作。
 
1.2.2 Array與Arrays的區別
     Arrays也是一個靜態類,專門用來操作array,提供搜索、排序等靜態方法,還提供一個允許把數組當作列表查看的靜態工廠方法asList。
 
 
第三節  其它常用方法總結(第四節爲使用中容易出現錯誤的方法介紹,第五節源代碼)
1.3.1 Collections中的常用方法
            java.util.Collections提供了一些靜態方法實現了基於list容器的一些常用算法:
1)  addAll(Collection c, T… elements);//將所有指定的元素添加到指定的collection中。
2)  void sort(List);//對list容器裏的元素進行排序
3)  void reverse(List);//對List容器對象進行逆序排序
4)  void copy(Listdest,List src)//將List src容器裏的內容全部拷貝到List dest容器中
5)   int binarySearch(List,Object)//對於順序的List容器中採用折半查找的方法查找特定的對象
6)   boolean disjoint(Collection c1, Collection c2);//如果兩個指定的collection中沒有相同的元素,返回true。
7)   fill(List list, T obj); // 使用指定元素替換指定列表中的所有元素。
8)   int frequency(Collection c, Object o);//返回指定的Collection中對於指定對象的元素數。
9)   indexOfSubList(List src, List target);//返回源表中第一次出現指定目標列表的起始位置,如果沒有這樣的列表就返回-1。
10) lastIndexOfSubList(List src, List target);//最後一次的起始位置,沒有則返回-1
11) max(Collection coll);//根據元素的自然順序,返回collection的最大值;
12) max(Collection coll,Comparator comp);//根據比較器產生的順序,返回最大元素。
13) min同上
14) replaceAll(List list, T oldVal, T newVal);//使用另外一個值替換列表中出現的所有某一指定值。
15) reverseOrder();//逆轉comparable接口的對象collection的自然順序。例如:假設a是一個字符串數組,那麼:
Arrays.sort(a, Collections.reverseOrder());將會按照字典逆序排序。
16) reverseOrder(Comparator cmp);返回一個強行逆轉比較器的順序
17) rotate(List list, intdistance);//根據指定的距離輪換列表中的元素。
18) shuffle(List list);//對列表隨機排序
19) shuffle(List list, Random rnd);//根據指定的隨機源排序
20) swap(List list, int i, int j);//在指定列表的指定位置處交換元素

 
[java] 


package chapter1; 
 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Collection; 
import java.util.Collections; 
import java.util.List; 
 
public class CollectionsMethod { 
 
    /**
     * @param args
     */ 
    public static void main(String[] args) { 
        List<Integer> collection = new ArrayList<Integer>(); 
         
        /*1----兩種方式 */ 
        Collections.addAll(collection, 1, 2, 3); 
        System.out.println(collection.toString()); 
         
        Integer[] moreInts = {10, 7, 4, 9}; 
        Collections.addAll(collection, moreInts); 
        System.out.println(collection.toString()); 
         
        /*2----簡單類型下sort的使用 */ 
        Collections.sort(collection); 
        System.out.println(collection.toString()); 
         
        /*3----逆序*/  
        Collections.reverse(collection); 
        System.out.println(collection.toString()); 
         
        /*4----複製*/  
        List<Integer> copyList = new  ArrayList(Arrays.asList( new  Object[collection.size()])); 
        Collections.copy(copyList, collection); 
        copyList.remove(0); 
        System.out.println(copyList.size()); 
        System.out.println(copyList.toString()); 
        System.out.println(collection.toString()); 
         
        /*4----另外一種方式 */  
        List array = new ArrayList(collection); 
        System.out.println(array.toString()); 
        System.out.println(collection.toString()); 
         
        /*5----二分查找,首先把列表排序才行 */ 
        List<Integer> bsList = new ArrayList<Integer>(); 
        bsList.add(9); 
        bsList.add(12); 
        bsList.add(2); 
        bsList.add(78); 
        bsList.add(10); 
        System.out.println(bsList.toString());       
        Collections.sort(bsList); 
        System.out.println(bsList); 
        int index = Collections.binarySearch(bsList, 20); 
        System.out.println(index); 
         
        /*6----判定兩個collection中是否沒有相同的元素,返回布爾值*/ 
        System.out.println(Collections.disjoint(bsList, array)); 
         
        /*7----返回指定對象的個數*/ 
        System.out.println(Collections.frequency(bsList, 10)); 
         
        /*8----子列表在指定列表中的位置*/ 
        List<Integer> subList = new ArrayList<Integer>(); 
        subList.add(9); 
        subList.add(10); 
        subList.add(5); 
        subList.add(1); 
        System.out.println(Collections.indexOfSubList(bsList, subList)); 
         
        /*9----返回最大最小值 & 倒序 & 循環移位 & 交換*/ 
        System.out.println(Collections.max(subList)); 
        Collections.reverseOrder(); 
        System.out.println(subList.toString()); 
        Collections.rotate(subList, 2); 
        System.out.println(subList.toString()); 
        Collections.swap(subList, 0, 2); 
        System.out.println(subList.toString()); 
         
         
    } 
 


1.3.2 Arrays中的常用方法
Arrays中的方法比較簡單,基本上分爲
1) asList方法,把一個數組轉換成list
2) 二分查找方法,可以指定在數組中的範圍內執行
3) toString方法
4) sort方法
 
第四節  容易出現錯誤的方法介紹
1.4.1Collections中容易出現錯誤的方法介紹
    1)copy方法
所以使用了Collections.copy()方法來進行拷貝,但是這樣就接觸到了此方法所報出的異常:
舉例如下:
List src1 = new  ArrayList( 3 )
src1.add( " a " );
src2.add( " b " );
src3.add( " c " );

如果你使用下面方法copy鏈表
/** **************************** */
List des1 = new  ArrayList( 3 );www.2cto.com
Collections.copy(des1,src1);
/** **************************** */
將會出錯,拋出數組越界異常。明明已經設置了長度爲3,爲什麼還會出錯?
打印出des1.size()才知道des1的長度爲0;3表示的是這個List的容納能力爲3,並不是說des1中就有了3個元素。查看api才知 道,它的capacity(容納能力大小)可以指定(最好指定)。而初始化時size的大小永遠默認爲0,只有在進行add和remove等相關操作 時,size的大小才變化。然而進行copy()時候,首先做的是將desc1的size和src1的size大小進行比較,只有當desc1的 size 大於或者等於src1的size時才進行拷貝,否則拋出IndexOutOfBoundsException異常。


作者:Allen_Zhao_2012



va中list裏面存放map,根據map中的某兩個個字段進行排序ja

package com.compare.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Main mainTest=new Main();
        mainTest.sortMap();
    }
    
    public  void sortMap(){
        List<Map<Integer, Double>> maps=new ArrayList<Map<Integer, Double>>();
        for(int i=0;i<10;i++){
            HashMap<Integer, Double> map=new HashMap<Integer, Double>();
            for(int j=0;j<2;j++){
                map.put(j, Math.random());
            }
            maps.add(map);
        }
        
        for(Map<Integer, Double>  map:maps){
            System.out.println(getValue(map));
        }
        System.out.println("************************");
        Map<Integer, Double> currentMap;
        for(int i=0;i<maps.size()-1;i++){
            for(int j=0;j<maps.size()-i-1;j++){
                if(getValue(maps.get(j))>getValue(maps.get(j+1))){
                    currentMap=maps.get(j+1);
                    maps.set(j+1, maps.get(j));
                    maps.set(j,currentMap);
                }
            }
        }
        
        for(Map<Integer, Double>  map:maps){
            System.out.println(getValue(map));
        }
        
        
        
    }
    
    public Double getValue(Map<Integer, Double> currentMap){
        return currentMap.get(0)+currentMap.get(1);
    }
    
    
    
    
}

我採用最簡單的排序大數沉底。而且getValue
方法你可以自己實現,決定使用哪幾個進行排序。(我們有進行key值不存在的判斷)




Java 對象多字段排序 Comparator


Java 反射類:ReflexUtil

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
publicclass ReflexUtil {
    staticLogger logger = LoggerFactory.getLogger(ReflexUtil.class);
 
    //getMethod
    staticpublic Object invokeMethod(String propertiesName, Object object) {
        try{
            if(object==null)returnnull;
            if(!propertiesName.contains(".")) {
                String methodName = "get"+getMethodName(propertiesName);
                Method method = object.getClass().getMethod(methodName);
                returnmethod.invoke(object);
            }
            String methodName = "get"+getMethodName(propertiesName.substring(0,propertiesName.indexOf(".")));
            Method method = object.getClass().getMethod(methodName);
            returninvokeMethod(propertiesName.substring(propertiesName.indexOf(".")+1), method.invoke(object));
 
        }catch(Exception e) {
            logger.error(e.toString(), e);
            returnnull;
        }
    }
 
    privatestatic String getMethodName(String fildeName) {
        byte[] items = fildeName.getBytes();
        items[0] = (byte) ((char) items[0] - 'a'+ 'A');
        returnnew String(items);
    }
 
    publicstatic void main(String args[]) {
        Video video = newVideo();
        Album album = newAlbum();
        album.setAlbumId(346l);
        video.setAlbum(album);
        video.setVideoId(126l);
        System.out.println(ReflexUtil.invokeMethod("album.albumId", video));
    }
}


Java 對象排序 : CompareUtil


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
publicclass CompareUtil {
 
    //sort 1正序 -1 倒序  filed 多字段排序
    publicstatic <t> Comparator createComparator(intsort, String... filed) {
        returnnew ImComparator(sort, filed);
    }
 
    publicstatic class ImComparator implementsComparator {
        intsort = 1;
        String[] filed;
 
        publicImComparator(intsort, String... filed) {
            this.sort = sort == -1? -1: 1;
            this.filed = filed;
        }
 
        @Override
        publicint compare(Object o1, Object o2) {
            intresult = 0;
            for(String file : filed) {
                Object value1 = ReflexUtil.invokeMethod(file, o1);
                Object value2 = ReflexUtil.invokeMethod(file, o2);
                if(value1 == null|| value2 == null) {
                    continue;
                }
                if(!(value1 instanceofInteger) || !(value1 instanceofInteger)) {
                    continue;
                }
                intv1 = Integer.valueOf(value1.toString());
                intv2 = Integer.valueOf(value2.toString());
                if(v1 == v2) continue;
                if(sort == 1) {
                    returnv1 - v2;
                }elseif (sort == -1) {
                    returnv2 - v1;
                }else{
                    continue;
                }
            }
            returnresult;
        }
    }
 
    publicstatic void main(String args[]) {
        LabelAlbum label1 = newLabelAlbum();
        label1.setLabelId(1); label1.setSequnces(1);
        LabelAlbum label2 = newLabelAlbum();
        label2.setLabelId(1);label2.setSequnces(2);
        LabelAlbum label3 = newLabelAlbum();
        label3.setLabelId(3); label3.setSequnces(4);
        LabelAlbum label4 = newLabelAlbum();
        label4.setLabelId(3);label4.setSequnces(3);
        LabelAlbum label5 = newLabelAlbum();
        label5.setLabelId(4);label5.setSequnces(2);
        List<labelalbum> list = newArrayList<labelalbum>();
        list.add(label1);
        list.add(label2);
        list.add(label3);
        list.add(label4);
        list.add(label5);
        Collections.sort(list, CompareUtil.createComparator(1,"labelId","sequnces"));
        for(inti = 0; i < list.size(); i++) {
            LabelAlbum labelAlbum=list.get(i);
            System.out.println("labelId:"+labelAlbum.getLabelId()+"  sequence:"+labelAlbum.getSequnces());
        }
    }
}</labelalbum></labelalbum></t>







mathmatic使用說明


http://wenku.baidu.com/link?url=qdl5Oxq54mo3Qdm1DglICS0uADeQhiVw13lCjjw2T-vxbzTDOYurdOGsAqrPDoBAQ9p4wbPGxkmntfaiFrCEpcSClIhYhvMH0IAIP7-Rpkm


http://wenku.baidu.com/link?url=ii01onq9srPE4pZoHLpm7oYp_S6xLeh0yMHAfKjO0Syp2eJtdxah055CRQQzVH01hsLzKzFuWySGAgoC1-mGnzOVowg3RTAtcnGS4Op494y



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章