java 按list对象多个字段排序

原创 2015年02月12日 13:47:50

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



相关文章推荐

java list按照元素对象的指定多个字段属性进行排序

java list按照元素对象的多个字段属性进行排序

Java中对单个或多个字段进行排序

Java中对单个字段或多个字段进行排序 import java.util.ArrayList; import java.util.Collections; import java.util.Comp...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

java多条件优先级排序 --- Comparator

package com; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator;...
  • jdsjlzx
  • jdsjlzx
  • 2014年11月13日 15:23
  • 8109

java Collections 排序--多条件排序

java Collection 排序–多条件排序// 气象告警排序 Collections.sort(domesticAirport, comparator);// 气象告警排序 Comparator...

java List多字段排序方法

java中对List接口的实例按实体的字段排序。如下例:package se;import java.util.ArrayList; import java.util.Collections; imp...

对List进行多维度排序

在java中,如果要对集合对象或数组对象进行排序,需要实现Comparator接口以达到我们想要的目标。 1 实体类 package domain; /** * Created by Johny ...

List多个字段排序、去重

List集合排序是通过java.util.Collections中的sort
  • siqilou
  • siqilou
  • 2014年11月13日 15:47
  • 1602

java 对象的排序 多字段比较 字符串排序

结果: [A [a=3, b=1, name=he], A [a=3, b=1, name=hello], A [a=1, b=2, name=null], A [a=2, b=10, name=n...

(好使)用Java集合中的Collections.sort方法对list排序的两种方法

用Collections.sort方法对list排序有两种方法 第一种是list中的对象实现Comparable接口,如下: /** * 根据order对User排序 */ public...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java 按list对象多个字段排序
举报原因:
原因补充:

(最多只允许输入30个字)