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
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( "."
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值