):Comparable接口和Comparator接口

读JDK源码(二

分类: 程序设计   288人阅读  评论(0)  收藏  举报

目录

1 介绍

2 Comparable接口

3 Comparator接口

4 总结

 

1 介绍

      有这样2个人,一个人光头,一个人有黑色头发,现在不允许染发,只允许光头的带假发,理由是有头发的人没有必要再带假发,那么谁可以有多种颜色的头发?在这种情况下,有头发的人,因为他的头发和自身绑定在一起,是无法在换头发的;而光头的头发(假发套)和其自身是不绑定的,可以根据自己喜欢换不同颜色的发套。有头发的人叫Comparable,光头不是孟飞,也不是乐嘉,叫Comparator。

 

 

    Comparable和Comparator是java中2个比较接口。Comparable是和具体类绑定的,我们称为“静态绑定”(如上图中有头发的人,头发是Comparable,头是具体的类)。而对于Comparator,具体的类在需要是可选择不同的Comparator绑定,是“动态绑定”(策略模式)(如上图中光头的人,假发是Comparator,头是具体的类,可根据需要选择不同的假发)。两者相比,Comparator比Comparable灵活,而且具体类可以在需要时选择不同的Comparator。

2 Comparable接口

    java.lang. Comparable接口定义类的自然顺序,实现该接口的类就可以按这种方式排序。Comparable只包含一个方法:

[java]  view plain copy
  1. public interface Comparable<T> {   
  2.   
  3.     public int compareTo(T o);   
  4.   
  5. }   
int compareTo(Object o): 比较当前实例对象与对象o,如果位于对象o之前,返回负值,如果两个对象在排序中位置相同,则返回0,如果位于对象o后面,则返回正值。String类实现了Comparable接口。
    需要比较或排序的对象,可以选择实现Comparable接口,自定义比较算法。
例子
[java]  view plain copy
  1. import java.util.Arrays;  
  2.   
  3. /**  
  4.  * @version 1.0 
  5.  * @date    2012-11-15 下午2:25:27  
  6.  * @fuction  实现Comparable接口 (先按序号比较,序号相等在比较姓名) */  
  7.   
  8.     public  class Student implements Comparable  
  9.     {  
  10.         //学号  
  11.         int num;  
  12.         //姓名  
  13.         String name;  
  14.           
  15.         //constructor  
  16.         public Student(int num,String name)  
  17.         {  
  18.             this.num=num;  
  19.             this.name=name;  
  20.         }  
  21.   
  22.         //重写java.lang中的接口Comparable的方法compareTo,定制比较的规则.但必须遵守比较规则(比较结果大返回正数,相等返回0,小返回负数)  
  23.         public int compareTo(Object o) {  
  24.             Student s=(Student)o;  
  25.             int result=num>s.num ? 1:(num==s.num ? 0: -1);  
  26.             //学号相等时,按名字排序  
  27.             if(0==result)  
  28.             {  
  29.                 //利用String的compareTo方法进行字符的比较  
  30.                 result=name.compareTo(s.name);  
  31.             }  
  32.             return result;  
  33.         }  
  34.   
  35.         @Override  
  36.         public String toString() {  
  37.             return "Student [num=" + num + ", name=" + name + "]";  
  38.         }  
  39.           
  40.           
  41.     /** 
  42.      * @param args 
  43.      */  
  44.     public static void main(String[] args) {  
  45.         Student[] test=new Student[]{new Student(2"wangwu"),  
  46.                                      new Student(1"lisi"),  
  47.                                      new Student(1"goudan") };  
  48.         //排序  
  49.         Arrays.sort(test);  
  50.           
  51.         //打印  
  52.         for(int i=0;i<test.length;i++)  
  53.         {  
  54.             System.out.println(test[i]);  
  55.               
  56.         }  
  57.           
  58.         //搜索姓名为“wangwu”的学生     
  59.         int index=Arrays.binarySearch(test,new Student(2,"wangwu"));   
  60.         System.out.println("查找的学生在数组中的位置:"+index);     
  61.     }  
  62.   
  63. }  

3 Comparator接口

 java.util.Comparator接口只包含2个方法

[java]  view plain copy
  1. int compare(T o1, T o2);  
[java]  view plain copy
  1. boolean equals(Object obj);  

int compare(T o1, T o2);比较用来排序的两个参数。 

boolean equals(Object obj);指示是否其他对象“等于”此 Comparator。

实现了compare接口的类具体的实现是在compare方法中自定义比较算法,然后将Comparator对象(实现了java.util.Comparator接口的对象)作为一个参数传递给欲比较或排序对象collection的某些排序方法。某些排序方法指的是能够接受java.util.Comparator参数的方法,比如:java.util. Arrays的public static void sort(Object[] a, Comparator c)和Collections的sort方法。

例子

[java]  view plain copy
  1. import java.util.Arrays;  
  2. import java.util.Comparator;  
  3.   
  4. /** 
  5.  * @version 1.0 
  6.  * @date 2012-11-15 下午11:21:09 
  7.  * @fuction 实现Comparator接口的比较算法 
  8.  *按学号排序 先按学号排序,学号相等时,按姓名排序 o1>o2返回1,o1=o2返回0,o1>o2返回-1 
  9.  */  
  10.   
  11. public class ByNumComparator implements Comparator {  
  12.   
  13.     public int compare(Object o1, Object o2) {  
  14.         Student s1 = (Student) o1;  
  15.         Student s2 = (Student) o2;  
  16.         // 按学号排序  
  17.         int result = s1.num > s2.num ? 1 : (s1.num == s2.num ? 0 : -1);  
  18.         // 学号相等时,按名字排序  
  19.         if (result == 0) {  
  20.             int copmpareName=s1.name.compareTo(s2.name);  
  21.         //利用String的compareTo方法进行字符的比较    
  22.            if(copmpareName>0)  
  23.             result=1;  
  24.            else if (copmpareName==0)  
  25.             result=0;  
  26.            else  
  27.             result=-1;  
  28.         }  
  29.   
  30.         return result;  
  31.     }  
  32.   
  33.     public static void main(String[] args) {  
  34.         Student[] test = new Student[] { new Student(2"wangwu"),  
  35.                 new Student(1"lisi"), new Student(1"goudan") };  
  36.         // 排序  
  37.         Arrays.sort(test, new ByNumComparator());  
  38.   
  39.         // 打印  
  40.         System.out.println("排序之后");  
  41.         for (int i = 0; i < test.length; i++) {  
  42.             System.out.println(test[i]);  
  43.   
  44.         }  
  45.   
  46.     }  
  47.   
  48. }  



输出结果:

排序之后
Student [num=1, name=goudan]
Student [num=1, name=lisi]
Student [num=2, name=wangwu]

4 总结

       一般在对对象进行比较或排序时,需要对象实现Comparable接口或者在使用排序方法(比如Arrays的sort)方法时,传入实现了Comparator接口的类的对象。


 

Comparable与Comparator的区别

分类: J2SE   1655人阅读  评论(4)  收藏  举报

 Comparable & Comparator 都是用来实现集合中元素的比较、排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。

Comparator位于包java.util下,而Comparable位于包   java.lang下

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

 自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,如API所说:
Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface
这里的自然顺序就是实现Comparable接口设定的排序方式。

而 Comparator 是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。
  
可以说一个是自已完成比较,一个是外部程序实现比较的差别而已。

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


// AbsComparator.java     
import   java.util.*;

public   class   AbsComparator   implements   Comparator   {     
    public   int   compare(Object   o1,   Object   o2)   {     
      int   v1   =   Math.abs(((Integer)o1).intValue());     
      int   v2   =   Math.abs(((Integer)o2).intValue());     
      return   v1   >   v2   ?   1   :   (v1   ==   v2   ?   0   :   -1);     
    }     
}

    
可以用下面这个类测试 AbsComparator:     

// Test.java     
import   java.util.*;     

public   class   Test   {     
    public   static   void   main(String[]   args)   {     
    
      //产生一个20个随机整数的数组(有正有负)     
      Random   rnd   =   new   Random();     
      Integer[]   integers   =   new   Integer[20];     
      for(int   i   =   0;   i   <   integers.length;   i++)     
      integers[i]   =   new   Integer(rnd.nextInt(100)   *   (rnd.nextBoolean()   ?   1   :   -1));     
    
      System.out.println("用Integer内置方法排序:");     
      Arrays.sort(integers);     
      System.out.println(Arrays.asList(integers));     
    
      System.out.println("用AbsComparator排序:");     
      Arrays.sort(integers,   new   AbsComparator());     
      System.out.println(Arrays.asList(integers));     
    }     
}



 Collections.sort((List<T> list, Comparator<? super T> c)是用来对list排序的。


如果不是调用sort方法,相要直接比较两个对象的大小,如下:
Comparator定义了俩个方法,分别是   int   compare(T   o1,   T   o2)和   boolean   equals(Object   obj),
用于比较两个Comparator是否相等
true only if the specified object is also a comparator and it imposes the same ordering as this comparator.
有时在实现Comparator接口时,并没有实现equals方法,可程序并没有报错,原因是实现该接口的类也是Object类的子类,而Object类已经实现了equals方法

 Comparable接口只提供了   int   compareTo(T   o)方法,也就是说假如我定义了一个Person类,这个类实现了   Comparable接口,那么当我实例化Person类的person1后,我想比较person1和一个现有的Person对象person2的大小时,我就可以这样来调用:person1.comparTo(person2),通过返回值就可以判断了;而此时如果你定义了一个   PersonComparator(实现了Comparator接口)的话,那你就可以这样:PersonComparator   comparator=   new   PersonComparator();
comparator.compare(person1,person2);。


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、下4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、下4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值