Comparable& Comparator

来源:互联网 发布:淘宝切片上传有空隙 编辑:程序博客网 时间:2024/06/07 11:01

java comparable

Comparator 

区别

 

Comparable 

Comparator 

都是用来实现集合中的排序的,只是

 

Comparable 

在集合内部定义的方法实现的排序,

 

Comparator 

是在集合外部实现的排序,所以,如想实现排序,就需要在集合外

定义

 

Comparator 

接口的方法或在集合内实现

 

Comparable 

接口的方法。

 

Comparable 

是一个对象本身就已经支持自比较所需要实现的接口(如

 

String

Integer 

自己就可以完成比较大小操作)

 

 

 

Comparator 

是一个专用的比较器,

当这个对象不支持自比较或者自比较函数

不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。

 

 

 

 

可以说一个是自己完成比较,一个是外部程序实现比较的差别而已。

 

 

 

 

 

Comparator 

是策略模式

strategy design pattern

就是不改变对象自身,

而用一个策略对象(

strategy object

)来改变它的行为。

 

 

 

 

比如:你想对整数采用绝对值大小来排序,

Integer 

是不符合要求的,你不

需要去修改

 

Integer 

类(实际上你也不能这么做)去改变它的排序行为,只要使

用一个实现了

 

Comparator 

接口的对象来实现控制它的排序就行了。

 

Comparator 

java.util

包中

 

Comparable 

java.lang

包中

 

 

 

 

 

 

public class TestComparator { 

 

 

 

 

AsComparator cl=new AsComparator(); 

 

 

 

 

/** *//** 

 

 

 

 

 

* @param args 

 

 

 

 

 

*/ 

 

 

 

 

 

 

@SuppressWarnings("unchecked") 

 

 

 

 

public static void main(String[] args) { 

 

 

 

 

 

 

 

 

 

Integer[] datas=new Integer[20];

Comparable& Comparator都是用来实现集合中的排序的,只是Comparable是在集合内部定义的方法实现的排序,

Comparator是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义Comparator接口的方法或在集合内实现Comparable接口的方法。

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

Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。


  可以说一个是自己完成比较,一个是外部程序实现比较的差别而已。


  用Comparator是策略模式(strategydesign pattern),就是不改变对象自身,而用一个策略对象(strategyobject)来改变它的行为。


  比如:你想对整数采用绝对值大小来排序,Integer是不符合要求的,你不需要去修改Integer类(实际上你也不能这么做)去改变它的排序行为,只要使用一个实现了Comparator接口的对象来实现控制它的排序就行了。

Comparatorjava.util包中

Comparablejava.lang包中


1 public class TestComparator {

2 AsComparator cl=new AsComparator();

3 /** *//**

4 * @param args

5 */

6 @SuppressWarnings("unchecked")

7 public static void main(String[] args) {

8 Integer[] datas=new Integer[20];

9 Random rand=new Random();

10 for(int i=0;i<20;i++){

11 datas[i]=new Integer(rand.nextInt(100));

12 }

13 Arrays.sort(datas);

14 System.out.println(Arrays.asList(datas));

15 TestComparator test=new TestComparator();

16 Arrays.sort(datas,test.cl);

17 System.out.println(Arrays.asList(datas));

18

19 }

20

21 @SuppressWarnings("rawtypes")

22 class AsComparator implements Comparator{

23

24 public int compare(Object o1, Object o2) {

25 int value1= Math.abs(((Integer)o1).intValue());

26 int value2=Math.abs(((Integer)o2).intValue());

27 return value1>value2?1:(value1==value2?0:-1);

28 }

29

30 }




排序的算法是我们最常用的算法,初学程序,每个人都尝试过排序。但只是局限于简单的排序。 

如将下列数字进行排序 
1,3,5,8,3,6 
于是我们得出结果 
1,3,3,5,6,8 
将下列字母(字符)进行排序 
a,i,e,f,w,s 
于是我们得出结果 
a,e,f,i,s,w 
但是我们遇到的情况就不是如此简单了。如给公司里的商品进行排序,我们很轻易的想到按照商品的名称排序不就完了,而且简单明了。但现实并如我们相信般简单。同一商品名称可以有不同的批次,进货时间,可能还会有单价的不同。显然只根据商品名称排序是不合理的。 

再举个简单例子然后用程序实现。如公司要将员工进行排序(不要说领导排在前面),假设我们的需求比较复杂。先进行姓排序,谁的姓拼音靠前,谁就排前面。然后对名字进行排序。恩.如果同名,女性排前头。如果名字和性别都相同,年龄小的排前头。ok,一个也不算复杂的需求。 

如果对java比较熟悉的会知道java.util.Comparator 接口。要实现里面的函数 
int compare(Object o1, Object o2) 返回一个基本类型的整型,返回负数表示o1 小于o2,返回0 表示o1和o2相等,返回正数表示o1大于o2。 

于是我们设计的人员类要有几个变量,firstname,lastname,sex,age分别表示姓,名,性别,年龄。 

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.   
  15.    public String getLastName() {  
  16.      return lastname;  
  17.    }  
  18.    public Boolean getSex() {  
  19.       return sex;  
  20.     }  
  21.   
  22.     public Integer getAge() {  
  23.       return age;  
  24.     }  
  25.   
  26. //为了输入方便,重写了toString()  
  27. public String toString()  
  28.     {  
  29.       return firstname +" "+lastname+" "+(sex.booleanValue()?"男":"女")+" "+age;  
  30.     }  
  31. }  
  32. //end person  


下面是要实现比较器 

Java代码  收藏代码
  1. public class Comparators {  
  2. public static java.util.Comparator getComparator() {  
  3.     return new java.util.Comparator() {  
  4.   
  5.       public int compare(Object o1, Object o2) {  
  6.         if (o1 instanceof String) {  
  7.           return compare( (String) o1, (String) o2);  
  8.         }else if (o1 instanceof Integer) {  
  9.           return compare( (Integer) o1, (Integer) o2);  
  10.         }else if (o1 instanceof Person) {  
  11.         return compare( (Person) o1, (Person) o2);  
  12.         }else {  
  13.           System.err.println("未找到合适的比较器");  
  14.           return 1;  
  15.   
  16.         }  
  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.   
  29.         while (n-- != 0) {  
  30.           char c1 = v1[pos];  
  31.           char c2 = v2[pos];  
  32.           if (c1 != c2) {  
  33.             return c1 - c2;  
  34.           }  
  35.           pos++;  
  36.         }  
  37.         return len1 - len2;  
  38.       }  
  39.   
  40.       public int compare(Integer o1, Integer o2) {  
  41.         int val1 = o1.intValue();  
  42.         int val2 = o2.intValue();  
  43.         return (val1 < val2 ? -1 : (val1 == val2 ? 0 : 1));  
  44.   
  45.       }  
  46.       public int compare(Boolean o1, Boolean o2) {  
  47.   
  48.          return (o1.equals(o2)? 0 : (o1.booleanValue()==true?1:-1));  
  49.   
  50.        }  
  51.   
  52.       public int compare(Person o1, Person o2) {  
  53.         String firstname1 = o1.getFirstName();  
  54.         String firstname2 = o2.getFirstName();  
  55.         String lastname1 = o1.getLastName();  
  56.         String lastname2 = o2.getLastName();  
  57.         Boolean sex1 = o1.getSex();  
  58.         Boolean sex2 = o2.getSex();  
  59.         Integer age1 = o1.getAge();  
  60.         Integer age2 = o2.getAge();  
  61.         return (compare(firstname1, firstname2) == 0 ?  
  62.              (compare(lastname1, lastname2) == 0 ? (compare(sex1, sex2) == 0 ? (compare(age1, age2) == 0 ? 0 :  
  63.               compare(age1, age2)) :  
  64.               compare(sex1, sex2)) :  
  65.               compare(lastname1, lastname2)) :  
  66.               compare(firstname1, firstname2));  
  67.   
  68.       }  
  69.   
  70.     };  
  71. }  
  72.   
  73. }  

以上代码有可能因为浏览器的布局自动换行。 
compare(Person o1, Person o2)的返回值看起来比较别扭。最简单的是 
Java代码  收藏代码
  1. public int compare(Boolean o1, Boolean o2) {  
  2.   
  3.      return (o1.equals(o2)? 0 : (o1.booleanValue()==true?1:-1));  
  4.   
  5.  }  


o1和o2相等返回0,否则o1如果是true 就表示o1大于o2。 

再尝试输出结果看看 


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.   
  12.      };  
  13.      for (int i = 0; i < person.length; i++) {  
  14.        System.out.println("before sort=" + person[i]);  
  15.      }  
  16.      java.util.Arrays.sort(person, Comparators.getComparator());  
  17.   
  18.      for (int i = 0; i < person.length; i++) {  
  19.         System.out.println("after sort=" + person[i]);  
  20.      }  
  21.   
  22.   
  23. }  
  24.   
  25. }  

输出结果: 

Java代码  收藏代码
  1. before sort=ouyang feng 男 27  
  2.   
  3. before sort=zhuang gw 男 27  
  4.   
  5. before sort=zhuang gw 女 27  
  6.   
  7. before sort=zhuang gw 女 2  
  8.   
  9. after sort=ouyang feng 男 27  
  10.   
  11. after sort=zhuang gw 女 2  
  12.   
  13. after sort=zhuang gw 女 27  
  14.   
  15. after sort=zhuang gw 男 27  
0 0