Java实现对象排序的两种方法

java中compareTo和compare方法之比较

这两个方法经常搞混淆,现对其进行总结以加深记忆。

  1. compareTo(Object o)方法是java.lang.Comparable<T>接口中的方法,当需要对某个类的对象进行排序时,该类需要实现Comparable<T>接口的,必须重写public int compareTo(T o)方法,比如MapReduce中Map函数和Reduce函数处理的 <key,value>,其中需要根据key对键值对进行排序,所以,key实现了WritableComparable<T>接口,实现这个接口可同时用于序列化和反序列化。WritableComparable<T>接口(用于序列化和反序列化)是Writable接口和Comparable<T>接口的组合;
  2. compare(Object o1,Object o2)方法是java.util.Comparator<T>接口的方法,它实际上用的是待比较对象的compareTo(Object o)方法。

AVA中Collections.sort()实现List排序的公共方法和自定义方法


1.java提供的默认list排序方法

主要代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
List<String> list = new ArrayList();
list.add("刘媛媛");
list.add("王硕");
list.add("李明");
list.add("刘迪");
list.add("刘布");
 
//升序
Collections.sort(list,Collator.getInstance(java.util.Locale.CHINA));//注意:是根据的汉字的拼音的字母排序的,而不是根据汉字一般的排序方法
for(int i=0;i<list.size();i++)
{
    System.out.print(list.get(i));
}
System.out.println("");
 
//降序
Collections.reverse(list);//不指定排序规则时,也是按照字母的来排序的
for(int i=0;i<list.size();i++)
{
     System.out.print(list.get(i));
}

输出结果:

李明刘布刘迪刘媛媛王硕
王硕刘媛媛刘迪刘布李明

 2.自定义的排序规则:

第一种是model类实现Comparable接口,重写重写int compareTo(Object o)方法

model类:

?
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
public class StudentDTO implements Comparable
{
 private String name;
 private int age;
 
 public String getName()
 {
    return name;
 }
 public void setName(String name)
 {
     this.name = name;
 }
 public ObjType getType()
 {
    return type;
 }
 public void setAge(int age)
 {
     this.age= age;
 }
 
 @Override
 public int compareTo(Object o)
 {
       StudentDTO sdto = (StudentDTO)o;
       int otherAge = sdto.getAge();
       //note: enum-type's comparation depend on types' list order of enum method
      //so, if compared property is enum-type ,then its comparationfollow ObjEnum.objType order
 
      return this.age.compareTo(otherAge);
 }
}

主方法:           

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args)
{
      List<StudentDTO> studentList = new ArrayList();
      StudentDTO s1 = new StudentDTO ();
      s.setName("yuanyuan");
      s.setAge(22);
      studentList.add(s1);
      StudentDTO s1 = new StudentDTO ();
      s.setName("lily");
      s.setAge(23);
      studentList.add(s2);
      Collections.sort(studentList);  //按照age升序 22,23,
      Collections.reverse(studentList);  //按照age降序 23,22  
}

通过实现Comparable接口实现个性化排序测试。排序测试,Collection.sort(list)升序排列Collections.sort(list, Collections.reverseOrder());降序排列;Collections.reverse(list);反转排序,先输出列表最后一个元素

第二种是比较器类实现Comparator接口,重写int compare(Object o1, Object o2)方法;

model类:          

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class StudentDTO implements Comparable
{
     private String name;
     private int age;
 
     public String getName()
     {
         return name;
     }
     public void setName(String name)
     {
         this.name = name;
     }
     public ObjType getType()
     {
         return type;
     }
     public void setAge(int age)
     {
         this.age= age;
     }
}

比较器类:

?
1
2
3
4
5
6
7
8
9
10
11
class MyCompartor implements Comparator
{
     @Override
     public int compare(Object o1, Object o2)
    {
           StudentDTO sdto1= (StudentDTO )o1;
           StudentDTO sdto2= (StudentDTO )o2;
 
          return sdto1.getAge.compareTo(stdo2.getAge())//按年龄从小到大排序
//return -sdto1.getAge.compareTo(stdo2.getAge())//按年龄从大到小排序
    } 
}

主方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args)
{
      List<StudentDTO> studentList = new ArrayList();
      StudentDTO s1 = new StudentDTO ();
      s.setName("yuanyuan");
      s.setAge(22);
      studentList.add(s1);
      StudentDTO s1 = new StudentDTO ();
      s.setName("lily");
      s.setAge(23);
      studentList.add(s2);
      MyComparetor mc = new MyComparetor();
      Collections.sort(studentList,mc);     //按照age升序 22,23
      Collections.reverse(studentList,mc);    //按照age降序 23,22 
}

附注:

1.对于数组的排序方法如下:

String[] names = {"王林",  "杨宝", "李镇", "刘迪", "刘波"};  
Arrays.sort(names, com.ibm.icu.text.Collator.getInstance(com.ibm.icu.util.ULocale.SIMPLIFIED_CHINESE));//升序;   
System.out.println(Arrays.toString(names));      

2.对于汉字的排序:可以尝试使用ICU4J会得到更好的结果,特别是姓为某些生僻字的时候,

用com.ibm.icu.text.Collator替换java.text.Collator,用com.ibm.icu.util.ULocale替换java.util.Locale

3.对于枚举类型的enum1.compareTo(enum2)是按照枚举类型值在定义时的先后顺序比较的,越后面的越大,而不是按照值的字母先后顺序比较的。





java实现对象比较,可以实现java.lang.Comparable或java.util.Comparator接口

Code:
  1. //Product.java
  2. import java.util.Date;   
  3.   
  4. //public class Product implements Comparable {//类内比较   
  5. public class Product{   
  6.   
  7.     private String name;   
  8.     private Date date;   
  9.     private int price;   
  10.        
  11.     public int getPrice() {   
  12.         return price;   
  13.     }   
  14.     public void setPrice(int price) {   
  15.         this.price = price;   
  16.     }   
  17.     public String getName() {   
  18.         return name;   
  19.     }   
  20.     public void setName(String name) {   
  21.         this.name = name;   
  22.     }   
  23.     public Date getDate() {   
  24.         return date;   
  25.     }   
  26.     public void setDate(Date date) {   
  27.         this.date = date;   
  28.     }   
  29. //用于类内比较
  30. //  @Override//覆写compareTo(Object o)方法   
  31. //  public int compareTo(Product o) {   
  32. //      return -this.date.compareTo(o.date);   
  33. //  }   
  34.        
  35. }  
Code:
  1. //ProductComparable.java   
  2.   
  3. import java.util.Date;   
  4. import java.util.Comparator;   
  5.   
  6. public class ProductComparable implements Comparator<Product> {   
  7.   
  8.     // 对象的排序方式[升、降]   
  9.     public static boolean sortASC = true;   
  10.   
  11.     // 对象的排序属性   
  12.     public static boolean sortByName = false;   
  13.     public static boolean sortByDate = false;   
  14.     public static boolean sortByPrice = false;   
  15.   
  16.        
  17.     @Override  
  18.     public int compare(Product pro1, Product pro2) {   
  19.   
  20.         int result = 0;   
  21.            
  22.         if(sortASC){   
  23.             if(sortByName){   
  24.                 String pro1name = pro1.getName();   
  25.                 String pro2name = pro2.getName();   
  26.                 result = pro1name.compareTo(pro2name);   
  27.             }else if(sortByDate){   
  28.                 Date pro1Date = pro1.getDate();   
  29.                 Date pro2Date = pro2.getDate();   
  30.                    
  31.                 result = pro1Date.compareTo(pro2Date);   
  32.                    
  33.             }else if(sortByPrice){   
  34.                 Integer pro1Price = pro1.getPrice();   
  35.                 Integer pro2Price = pro2.getPrice();   
  36.                    
  37.                 result = pro1Price.compareTo(pro2Price);   
  38.             }   
  39.         }else{   
  40.             if(sortByName){   
  41.                 String pro1name = pro1.getName();   
  42.                 String pro2name = pro2.getName();   
  43.                    
  44.                 result =  -pro1name.compareTo(pro2name);   
  45.             }else if(sortByDate){   
  46.                 Date pro1Date = pro1.getDate();   
  47.                 Date pro2Date = pro2.getDate();   
  48.                    
  49.                 result =  -pro1Date.compareTo(pro2Date);   
  50.                    
  51.             }else if(sortByPrice){   
  52.                 Integer pro1Price = pro1.getPrice();   
  53.                 Integer pro2Price = pro2.getPrice();   
  54.                    
  55.                 result =  -pro1Price.compareTo(pro2Price);   
  56.             }   
  57.         }   
  58.         return result;   
  59.     }   
  60.   
  61. }  
Code:
  1. //测试代码   
  2.   
  3. import java.text.ParseException;   
  4. import java.text.SimpleDateFormat;   
  5. import java.util.ArrayList;   
  6. import java.util.Collections;   
  7. import java.util.Iterator;   
  8. import java.util.List;   
  9. import java.util.Locale;   
  10.   
  11. public class ProductSort {   
  12.   
  13.     public static void main(String[] args) throws ParseException {   
  14.         Product pro1 = new Product();   
  15.         pro1.setName("pro1");   
  16.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-dd-MM",Locale.CHINA);   
  17.         pro1.setDate(sdf.parse("2009-03-23"));   
  18.         pro1.setPrice(89);   
  19.         Product pro2 = new Product();   
  20.         pro2.setName("proc2");   
  21.         pro2.setDate(sdf.parse("2009-02-23"));   
  22.         pro2.setPrice(45);   
  23.         Product pro3 = new Product();   
  24.         pro3.setName("proc3");   
  25.         pro3.setDate(sdf.parse("2009-01-23"));   
  26.         pro3.setPrice(83);   
  27.         Product pro4 = new Product();   
  28.         pro4.setName("proc4");   
  29.         pro4.setDate(sdf.parse("2009-01-23"));   
  30.         pro4.setPrice(800);   
  31.            
  32.            
  33.         List<Product> productList = new ArrayList<Product>();   
  34.         productList.add(pro1);   
  35.         productList.add(pro3);   
  36.         productList.add(pro2);   
  37.         productList.add(pro4);   
  38.            
  39.         System.out.println("排序前————————————————————");   
  40.         for(Product p: productList){   
  41.             System.out.println(p.getName()+"----"+p.getPrice()+"----"+p.getDate());   
  42.         }   
  43.         ProductComparable sort = new ProductComparable();   
  44.            
  45.         ProductComparable.sortASC = false;//降序   
  46.         ProductComparable.sortByPrice=true;  //设置排序属性生效 
  47.         Collections.sort(productList,sort);   
  48.            
  49.         System.out.println("排序后————————————————————");   
  50.            
  51.         for(Iterator<Product>  iter = productList.iterator(); iter.hasNext();){   
  52.             Product p = (Product)iter.next();   
  53.             System.out.println(p.getName()+"----"+p.getPrice()+"---"+p.getDate());   
  54.         }   
  55.     }   
  56. }  

 推荐使用Comparator实现排序

因为 你用一个第三方的类,但他没实现Comparable接口,而你又不能改他代码;另外,类一旦写好后是不允许修改的,但可以扩展,所以只能用Comparator接口




java实现对象比较,可以实现java.lang.Comparable或java.util.Comparator接口

Code:
  1. //Product.java
  2. import java.util.Date;   
  3.   
  4. //public class Product implements Comparable {//类内比较   
  5. public class Product{   
  6.   
  7.     private String name;   
  8.     private Date date;   
  9.     private int price;   
  10.        
  11.     public int getPrice() {   
  12.         return price;   
  13.     }   
  14.     public void setPrice(int price) {   
  15.         this.price = price;   
  16.     }   
  17.     public String getName() {   
  18.         return name;   
  19.     }   
  20.     public void setName(String name) {   
  21.         this.name = name;   
  22.     }   
  23.     public Date getDate() {   
  24.         return date;   
  25.     }   
  26.     public void setDate(Date date) {   
  27.         this.date = date;   
  28.     }   
  29. //用于类内比较
  30. //  @Override//覆写compareTo(Object o)方法   
  31. //  public int compareTo(Product o) {   
  32. //      return -this.date.compareTo(o.date);   
  33. //  }   
  34.        
  35. }  
Code:
  1. //ProductComparable.java   
  2.   
  3. import java.util.Date;   
  4. import java.util.Comparator;   
  5.   
  6. public class ProductComparable implements Comparator<Product> {   
  7.   
  8.     // 对象的排序方式[升、降]   
  9.     public static boolean sortASC = true;   
  10.   
  11.     // 对象的排序属性   
  12.     public static boolean sortByName = false;   
  13.     public static boolean sortByDate = false;   
  14.     public static boolean sortByPrice = false;   
  15.   
  16.        
  17.     @Override  
  18.     public int compare(Product pro1, Product pro2) {   
  19.   
  20.         int result = 0;   
  21.            
  22.         if(sortASC){   
  23.             if(sortByName){   
  24.                 String pro1name = pro1.getName();   
  25.                 String pro2name = pro2.getName();   
  26.                 result = pro1name.compareTo(pro2name);   
  27.             }else if(sortByDate){   
  28.                 Date pro1Date = pro1.getDate();   
  29.                 Date pro2Date = pro2.getDate();   
  30.                    
  31.                 result = pro1Date.compareTo(pro2Date);   
  32.                    
  33.             }else if(sortByPrice){   
  34.                 Integer pro1Price = pro1.getPrice();   
  35.                 Integer pro2Price = pro2.getPrice();   
  36.                    
  37.                 result = pro1Price.compareTo(pro2Price);   
  38.             }   
  39.         }else{   
  40.             if(sortByName){   
  41.                 String pro1name = pro1.getName();   
  42.                 String pro2name = pro2.getName();   
  43.                    
  44.                 result =  -pro1name.compareTo(pro2name);   
  45.             }else if(sortByDate){   
  46.                 Date pro1Date = pro1.getDate();   
  47.                 Date pro2Date = pro2.getDate();   
  48.                    
  49.                 result =  -pro1Date.compareTo(pro2Date);   
  50.                    
  51.             }else if(sortByPrice){   
  52.                 Integer pro1Price = pro1.getPrice();   
  53.                 Integer pro2Price = pro2.getPrice();   
  54.                    
  55.                 result =  -pro1Price.compareTo(pro2Price);   
  56.             }   
  57.         }   
  58.         return result;   
  59.     }   
  60.   
  61. }  
Code:
  1. //测试代码   
  2.   
  3. import java.text.ParseException;   
  4. import java.text.SimpleDateFormat;   
  5. import java.util.ArrayList;   
  6. import java.util.Collections;   
  7. import java.util.Iterator;   
  8. import java.util.List;   
  9. import java.util.Locale;   
  10.   
  11. public class ProductSort {   
  12.   
  13.     public static void main(String[] args) throws ParseException {   
  14.         Product pro1 = new Product();   
  15.         pro1.setName("pro1");   
  16.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-dd-MM",Locale.CHINA);   
  17.         pro1.setDate(sdf.parse("2009-03-23"));   
  18.         pro1.setPrice(89);   
  19.         Product pro2 = new Product();   
  20.         pro2.setName("proc2");   
  21.         pro2.setDate(sdf.parse("2009-02-23"));   
  22.         pro2.setPrice(45);   
  23.         Product pro3 = new Product();   
  24.         pro3.setName("proc3");   
  25.         pro3.setDate(sdf.parse("2009-01-23"));   
  26.         pro3.setPrice(83);   
  27.         Product pro4 = new Product();   
  28.         pro4.setName("proc4");   
  29.         pro4.setDate(sdf.parse("2009-01-23"));   
  30.         pro4.setPrice(800);   
  31.            
  32.            
  33.         List<Product> productList = new ArrayList<Product>();   
  34.         productList.add(pro1);   
  35.         productList.add(pro3);   
  36.         productList.add(pro2);   
  37.         productList.add(pro4);   
  38.            
  39.         System.out.println("排序前————————————————————");   
  40.         for(Product p: productList){   
  41.             System.out.println(p.getName()+"----"+p.getPrice()+"----"+p.getDate());   
  42.         }   
  43.         ProductComparable sort = new ProductComparable();   
  44.            
  45.         ProductComparable.sortASC = false;//降序   
  46.         ProductComparable.sortByPrice=true;  //设置排序属性生效 
  47.         Collections.sort(productList,sort);   
  48.            
  49.         System.out.println("排序后————————————————————");   
  50.            
  51.         for(Iterator<Product>  iter = productList.iterator(); iter.hasNext();){   
  52.             Product p = (Product)iter.next();   
  53.             System.out.println(p.getName()+"----"+p.getPrice()+"---"+p.getDate());   
  54.         }   
  55.     }   
  56. }  

 推荐使用Comparator实现排序

因为 你用一个第三方的类,但他没实现Comparable接口,而你又不能改他代码;另外,类一旦写好后是不允许修改的,但可以扩展,所以只能用Comparator接口


没有更多推荐了,返回首页