java 按list对象多个字段排序

Java List中的数据如何根据对象的某一个或多个字段排序引出Comparable和comparator的使用
     

第一节  对于引入题目的探讨
首先把引入题目表述的清楚一些,在一个List中存储的是一些对象实例,而对象实例包含多个属性字段,我们要根据对象的某个或者多个属性来对List进行排序。
假设List中存储的都是Student类的实例,Student类包含name、gender、id属性。首先根据Student实例中的name属性排序,如果两个名字相同,就再根据id属性排序。
Student类源码如下:
[java] 

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; 
    } 
}
 
          假设有三个学生:

                                     姓名       性别        ID
                                     宋超       男          100120
                                     伍星       男          100121
                                     宋超       女          100122
            把这三个学生存储在List里面,要求首先按照姓名进行排序,如果姓名相同就按照ID排序。
 
1.1.1第一种实现方式:使用Comparable接口;
          使用这种方式时,Student类必须继承这个接口,并且实现compareTo方法。并且compareTo方法是这个接口的唯一方法。需要注意到一点,在《Effective Java》第十二条中,提供了一个通用的写法,也就是在类继承的Comparable接口的时候,利用泛型指明能比较的类型。把Student类改写如下:
              
[java] 


package chapter1; 
  
public classStudent implementsComparable
    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"); 
                            
                            Liststudents = new ArrayList(); 
                            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() { 
  
            @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() { 
 
           @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 collection = new ArrayList(); 
         
        /*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 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 bsList = new ArrayList(); 
        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 subList = new ArrayList(); 
        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> maps=new ArrayList>();
        for(int i=0;i<10;i++){
            HashMap map=new HashMap();
            for(int j=0;j<2;j++){
                map.put(j, Math.random());
            }
            maps.add(map);
        }
        
        for(Map  map:maps){
            System.out.println(getValue(map));
        }
        System.out.println("************************");
        Map currentMap;
        for(int i=0;igetValue(maps.get(j+1))){
                    currentMap=maps.get(j+1);
                    maps.set(j+1, maps.get(j));
                    maps.set(j,currentMap);
                }
            }
        }
        
        for(Map  map:maps){
            System.out.println(getValue(map));
        }
        
        
        
    }
    
    public Double getValue(Map 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
public class ReflexUtil {
     static Logger logger = LoggerFactory.getLogger(ReflexUtil. class );
 
     //getMethod
     static public Object invokeMethod(String propertiesName, Object object) {
         try {
             if (object== null ) return null ;
             if (!propertiesName.contains( "." )) {
                 String methodName = "get" +getMethodName(propertiesName);
                 Method method = object.getClass().getMethod(methodName);
                 return method.invoke(object);
             }
             String methodName = "get" +getMethodName(propertiesName.substring( 0 ,propertiesName.indexOf( "." )));
             Method method = object.getClass().getMethod(methodName);
             return invokeMethod(propertiesName.substring(propertiesName.indexOf( "." )+ 1 ), method.invoke(object));
 
         } catch (Exception e) {
             logger.error(e.toString(), e);
             return null ;
         }
     }
 
     private static String getMethodName(String fildeName) {
         byte [] items = fildeName.getBytes();
         items[ 0 ] = ( byte ) (( char ) items[ 0 ] - 'a' + 'A' );
         return new String(items);
     }
 
     public static void main(String args[]) {
         Video video = new Video();
         Album album = new Album();
         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
public class CompareUtil {
 
     //sort 1正序 -1 倒序  filed 多字段排序
     public static Comparator createComparator( int sort, String... filed) {
         return new ImComparator(sort, filed);
     }
 
     public static class ImComparator implements Comparator {
         int sort = 1 ;
         String[] filed;
 
         public ImComparator( int sort, String... filed) {
             this .sort = sort == - 1 ? - 1 : 1 ;
             this .filed = filed;
         }
 
         @Override
         public int compare(Object o1, Object o2) {
             int result = 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 instanceof Integer) || !(value1 instanceof Integer)) {
                     continue ;
                 }
                 int v1 = Integer.valueOf(value1.toString());
                 int v2 = Integer.valueOf(value2.toString());
                 if (v1 == v2) continue ;
                 if (sort == 1 ) {
                     return v1 - v2;
                 } else if (sort == - 1 ) {
                     return v2 - v1;
                 } else {
                     continue ;
                 }
             }
             return result;
         }
     }
 
     public static void main(String args[]) {
         LabelAlbum label1 = new LabelAlbum();
         label1.setLabelId( 1 ); label1.setSequnces( 1 );
         LabelAlbum label2 = new LabelAlbum();
         label2.setLabelId( 1 );label2.setSequnces( 2 );
         LabelAlbum label3 = new LabelAlbum();
         label3.setLabelId( 3 ); label3.setSequnces( 4 );
         LabelAlbum label4 = new LabelAlbum();
         label4.setLabelId( 3 );label4.setSequnces( 3 );
         LabelAlbum label5 = new LabelAlbum();
         label5.setLabelId( 4 );label5.setSequnces( 2 );
         List list = new ArrayList();
         list.add(label1);
         list.add(label2);
         list.add(label3);
         list.add(label4);
         list.add(label5);
         Collections.sort(list, CompareUtil.createComparator( 1 , "labelId" , "sequnces" ));
         for ( int i = 0 ; i < list.size(); i++) {
             LabelAlbum labelAlbum=list.get(i);
             System.out.println( "labelId:" +labelAlbum.getLabelId()+ "  sequence:" +labelAlbum.getSequnces());
         }
     }
}

java 按list对象多个字段排序_第1张图片







mathmatic使用说明


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


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



你可能感兴趣的:(JAVA开发)