java comparable 和 comparator 排序
阅读原文时间:2021年04月20日阅读:1

当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序 

Comparable是一个对象本身就已经支持自比较所需要实现的接口(如String Integer自己就可以完成比较大小操作) 

而Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。 
    comparable是通用的接口,用户可以实现它来完成自己特定的比较,而comparator可以看成一种算法的实现,在需要容器集合collection需要比较功能的时候,来指定这个比较器,这可以看出一种设计模式   
   comparable应该比较固定,和一个具体类相绑定,而comparator比较灵活,它可以被用于各个需要比较功能的类使用。可以说前者属于“静态绑定”,而后者可以“动态绑定”。 
  一个类实现了Camparable接口表明这个类的对象之间是可以相互比较的。如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这个类对象组成的集合就可以使用Sort方法排序了。 
  而Comparator的作用有两个: 
  1. 如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过 Comparator来实现比较算法进行排序 
  2. 为了使用不同的排序标准做准备,比如:升序、降序或其他什么序 
用法: 
实现comparable类的实例就是可以排序的,重写compareTo(),只要调用sort(Object[] a)方法就可以,如果没有实现comparable接口,却调用sort(Object[] a)方法就会报错,因为sort()里面用到的mergeSort()方法将a转化成Comparable类型调用compareTo(T o)方法。 
例子: 
一。实现comparable接口 

Java代码 

  1. import java.util.Arrays;   
  2. public class User implements Comparable {   
  3. private String id;  
  4. private int age;   
  5. public User(String id,int age) {  
  6.     this.id = id;  
  7.     this.age = age;  
  8. }   
  9. public int getAge() {  
  10.     return age;  
  11. }   
  12. public void setAge(int age) {  
  13.     this.age = age;  
  14. }   
  15. public String getId() {  
  16.     return id;  
  17. }   
  18. public void setId(String id) {  
  19.     this.id = id;  
  20. }   
  21. public int compareTo(Object o) {  
  22.     return this.age - ((User) o).getAge();  
  23. }   
  24. /** 
  25. * 测试方法 
  26. */  
  27. public static void main(String[] args) {  
  28.     User[] users = new User[] { new User("a", 30), new User("b", 20) };  
  29.     Arrays.sort(users);  
  30.     for (int i = 0; i < users.length; i++) {  
  31.       User user = users[i];  
  32.       System.out.println(user.getId() + " " + user.getAge());  
  33.     }  
  34. }   
  35. }   

二。comparator接口 

Java代码 

  1. public class Person {  

  2. String firstname,lastname;  

  3. Boolean sex;  

  4. Integer age;  

  5. public Person(String firstname,String lastname,Boolean sex,Integer age) {  

  6.     this.firstname = firstname;  

  7.     this.lastname = lastname;  

  8.     this.sex = sex;  

  9.     this.age = age;  

  10. }  

  11. public String getFirstName() {  

  12.      return firstname;  

  13.    }  

  14.    public String getLastName() {  

  15.      return lastname;  

  16.    }  

  17.    public Boolean getSex() {  

  18.       return sex;  

  19.     }  

  20.     public Integer getAge() {  

  21.       return age;  

  22.     }  

  23. //为了输入方便,重写了toString()  

  24. public String toString()  

  25.     {  

  26.       return firstname +" "+lastname+" "+(sex.booleanValue()?"男":"女")+" "+age;  

  27.     }  

  28. }  

  29. //end person  

下面是要实现比较器 

Java代码 

  1. public class Comparators {  

  2. public static java.util.Comparator getComparator() {  

  3.     return new java.util.Comparator() {  

  4.       public int compare(Object o1, Object o2) {  

  5.         if (o1 instanceof String) {  

  6.           return compare( (String) o1, (String) o2);  

  7.         }  

  8.        else if (o1 instanceof Integer) {  

  9.           return compare( (Integer) o1, (Integer) o2);  

  10.         }  

  11.        else if (o1 instanceof Person) {  

  12.       return compare( (Person) o1, (Person) o2);  

  13.     }  

  14.         else {  

  15.           System.err.println("未找到合适的比较器");  

  16.           return 1;  

  17.         }  

  18.       }  

  19.       public int compare(String o1, String o2) {  

  20.         String s1 = (String) o1;  

  21.         String s2 = (String) o2;  

  22.         int len1 = s1.length();  

  23.         int len2 = s2.length();  

  24.         int n = Math.min(len1, len2);  

  25.         char v1[] = s1.toCharArray();  

  26.         char v2[] = s2.toCharArray();  

  27.         int pos = 0;  

  28.         while (n-- != 0) {  

  29.           char c1 = v1[pos];  

  30.           char c2 = v2[pos];  

  31.           if (c1 != c2) {  

  32.             return c1 - c2;  

  33.           }  

  34.           pos++;  

  35.         }  

  36.         return len1 - len2;  

  37.       }  

  38.       public int compare(Integer o1, Integer o2) {  

  39.         int val1 = o1.intValue();  

  40.         int val2 = o2.intValue();  

  41.         return (val1 < val2 ? -1 : (val1 == val2 ? 0 : 1));  

  42.       }  

  43.       public int compare(Boolean o1, Boolean o2) {  

  44.          return (o1.equals(o2)? 0 : (o1.booleanValue()==true?1:-1));  

  45.        }  

  46.       public int compare(Person o1, Person o2) {  

  47.         String firstname1 = o1.getFirstName();  

  48.         String firstname2 = o2.getFirstName();  

  49.         String lastname1 = o1.getLastName();  

  50.         String lastname2 = o2.getLastName();  

  51.         Boolean sex1 = o1.getSex();  

  52.         Boolean sex2 = o2.getSex();  

  53.         Integer age1 = o1.getAge();  

  54.         Integer age2 = o2.getAge();  

  55.         return (compare(firstname1, firstname2) == 0 ?  

  56.                 (compare(lastname1, lastname2) == 0 ? (compare(sex1, sex2) == 0 ? (compare(age1, age2) == 0 ? 0 :  

  57.                  compare(age1, age2)) :  

  58.                  compare(sex1, sex2)) :  

  59.                  compare(lastname1, lastname2)) :  

  60.                 compare(firstname1, firstname2));  

  61.       }  

  62.     };  

  63. }  

  64. }  

//测试 

Java代码 

  1. public class Main {  

  2. public Main() {  

  3. }  

  4. public static void main(String[] args) {  

  5.     Person[] person = new Person[] {  

  6.          new Person("ouyang", "feng", Boolean.TRUE, new Integer(27)),  

  7.          new Person("zhuang", "gw", Boolean.TRUE, new Integer(27)),  

  8.          new Person("zhuang", "gw", Boolean.FALSE, new Integer(27)),  

  9.          new text.Person("zhuang", "gw", Boolean.FALSE, new Integer(2))  

  10.      };  

  11.      for (int i = 0; i < person.length; i++) {  

  12.        System.out.println("before sort=" + person[i]);  

  13.      }  

  14.      java.util.Arrays.sort(person, Comparators.getComparator());  

  15.     for (int i = 0; i < person.length; i++) {  

  16.       System.out.println("after sort=" + person[i]);  

  17.     }  

  18. }  

  19. }  

另一个从网上摘的例子: 
1,comparator 

Java代码 

  1. import java.util.Arrays;     

  2. import java.util.Comparator;     

  3. public class SampleComparator implements Comparator {     

  4.   public int compare(Object o1, Object o2) {     

  5.     return toInt(o1) - toInt(o2);     

  6.   }     

  7.   private int toInt(Object o) {     

  8.     String str = (String) o;     

  9.     str = str.replaceAll("一", "1");     

  10.     str = str.replaceAll("二", "2");     

  11.     str = str.replaceAll("三", "3");     

  12.     //   

  13.     return Integer.parseInt(str);     

  14.   }     

  15.   /**  

  16. * 测试方法  

  17. */    

  18.   public static void main(String[] args) {     

  19.     String[] array = new String[] { "一二", "三", "二" };     

  20.     Arrays.sort(array, new SampleComparator());     

  21.     for (int i = 0; i < array.length; i++) {     

  22.       System.out.println(array[i]);     

  23.     }     

  24.   }     

  25. }  

  

2,comparable 

Java代码 

  1. import java.util.Arrays;     

  2. public class User implements Comparable {     

  3.   private String id;     

  4.   private int age;     

  5.   public User(String id, int age) {     

  6.     this.id = id;     

  7.     this.age = age;     

  8.   }     

  9.   public int getAge() {     

  10.     return age;     

  11.   }     

  12.   public void setAge(int age) {     

  13.     this.age = age;     

  14.   }     

  15.   public String getId() {     

  16.     return id;     

  17.   }     

  18.   public void setId(String id) {     

  19.     this.id = id;     

  20.   }     

  21.   public int compareTo(Object o) {     

  22.     return this.age - ((User) o).getAge();     

  23.   }     

  24.   /**  

  25. * 测试方法  

  26. */    

  27.   public static void main(String[] args) {     

  28.     User[] users = new User[] { new User("a", 30), new User("b", 20) };     

  29.     Arrays.sort(users);     

  30.     for (int i = 0; i < users.length; i++) {     

  31.       User user = users[i];     

  32.       System.out.println(user.getId() + " " + user.getAge());     

  33.     }     

  34.   }     

  35. }    

Java代码 

  1. import java.util.Arrays;     

  2. import java.util.Comparator;     

  3. public class UserComparator implements Comparator {     

  4.   public int compare(Object o1, Object o2) {     

  5.     return ((User) o1).getAge() - ((User) o2).getAge();     

  6.   }     

  7.   /**  

  8. * 测试方法  

  9. */    

  10.   public static void main(String[] args) {     

  11.     User[] users = new User[] { new User("a", 30), new User("b", 20) };     

  12.     Arrays.sort(users, new UserComparator());     

  13.     for (int i = 0; i < users.length; i++) {     

  14.       User user = users[i];     

  15.       System.out.println(user.getId() + " " + user.getAge());     

  16.     }     

  17.   }     

  18. }    

http://hi.baidu.com/kinny/blog/item/4b3eba7e93c453380cd7da16.html 摘的一段: 
1.对象本身实现Comparable接口,那么该类的实例就是可以排序的. 
有关Comparable: http://blog.csdn.net/treeroot/archive/2004/09/09/99613.aspx 
只要实现了Comparable接口,就可以调用Collections的sort方法对集合中的元素排序. 

2.指定一个Comparator,也就是实现了Comparator的类的一个实例. 
但是Java本身只提供了一个Comparator的实现,就是Collections.reverseOrder(). 
该方法返回的是一个已经实现了Comparable接口的反序. 

看一下Comparator的全部内容: 

public interface Comparator { 
  int compare(Object o1, Object o2); 
  boolean equals(Object obj); 

定义了两个方法,其实我们一般都只需要实现compare方法就行了,因为类都是默认从Object继承 
所以会使用Object的equals方法. 
Comparator一般都作为一个匿名类出现,对于没有实现Comparable的对象的集合,排序的时候 
需要指定一个Comparator.