Comparable接口和Comparator接口

    看了一些网上写的关于Comparable接口和Comparator接口和Comparator接口的比较和区别,感觉写的不是很好,没有和说到点子上。本人也一直都在使用Comparable接口实现排序,虽然知道Comparator接口也可以实现这个功能,但是从来没用过,碰巧今天在做Topcoder的时候遇到了这么一个必须使用Comparator接口的题目,让我真正理解了Comparable接口和Comparator接口的区别。

    下面就介绍一下这个题目:要求对一个字符串数组进行排序,每个字符串都是由字符大写字母'A'-'Z'和数字'0'-'9'组成的,排序的规则如下:

1. 如果String A的长度小于String B,则A排在B前面,即A<B;

2. 否则,如果字符串长度相等,则比较字符串中每个数字的和,和小的排在前面;

3. 否则,如果字符串长度相等并且每个数字的和也相等,则按照正常的字母表顺序来比较。

 

    乍一看这个题似乎很简单,就是定义一个新的比较规则,排序的时候调用就行了,但是仔细一想还是不对,String类本身已经实现了一个CompareTo方法了,我们无法修改这个CompareTo方法的实现。但是如果我们自己定义一个类也不行,因为要求是比较一个字符串数组,所以每个比较的元素必须是字符串,总而言之就是,我们现在要修改String的比较规则,让s1.compareTo(s2)按照我们的规则来实现,然而,我们无法通过让一个类实现Comparable接口来完成这个任务。

    所以我想到了让一个类实现Comparator接口,然后实现里面的Compare方法,compare方法的参数有两个,我们可以定义泛型来让这两个参数变成String类型。然后添加新的比较规则,最后还要用到老的比较规则。

    如果还是有点不懂,没关系,看看下面的代码自然就懂了。

import java.util.*;

public class SerialNumbers implements Comparator<String> {
 

    public String[] sortSerials(String[] serialNumbers) {
          List<String> list = new ArrayList<String>();
          for(int i=0; i<serialNumbers.length; i++) {
                list.add(serialNumbers[i]);
          }
          Collections.sort(list, this);
          String[] ans = new String[list.size()];
          for(int j=0; j<list.size(); j++) {
                 ans[j] = list.get(j);
          }
       return ans;
     }

     public int compare(String s1, String s2) {
          int len1 = s1.length();
          int len2 = s2.length();
          int ret = len1 < len2 ? -1 : (len1 == len2 ? 0 : 1);
          if(ret != 0) {
                return ret;
      }
      else {
            int n1 = getNum(s1);
            int n2 = getNum(s2);
            ret = n1 < n2 ? -1 : (n1 == n2 ? 0 : 1);
            if(ret != 0) {
                return ret;
       } else {
             return s1.compareTo(s2);
       }
    }
 }

     public int getNum(String s) {
          int len = s.length();
          char[] ch = s.toCharArray();
          int sum = 0;
          for(int i=0; i<len; i++) {
               if(ch[i] >= '0' && ch[i] <='9') {
                    sum += (ch[i]-'0');
          }
  }
  return sum;
 }
}

 

    相信在看了代码以后就应该明白些了吧,现在再简单说一下Comparable接口和Comparator接口之间的区别(纯属个人想法)。我觉得Comparable接口的最大作用就在于定义一个自定义的类的比较规则,因为CompareTo方法只有一个参数,另一个参数是this,也就是这个类本身,所以我们可以把它看成是在类的内部定义比较规则,相当于Java开发人员在写String类的时候就应该让它实现Comparable接口。然而,compare方法有两个参数,这两个参数可以是任意类型的,可以是已经定义过的String类型,也可以是自定义的类型。如果是已经定义过的类型,compare方法可以对它的规则进行重新定义,如果是自定义的类型,可以新定义一个规则。

 

总结:

comparable是支持自比较,而后者是支持外部比较;

comparable&   Comparator    都是用来实现集合中的排序的,只是Comparable是在集合内部定义的方法实现的排序,Comparator是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义Comparator接口的方法compare()或在集合内实现Comparable接口的方法compareTo()。

Comparable是一个对象本身就已经支持自比较所需要实现的接口(如String    Integer自己就可以完成比较大小操作)  
   
   而Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。

    也就是说当你需要对一个自定义的类的一个数组或者集合进行比较的时候可以实现Comparable接口,当你需要对一个已有的类的数组或者集合进行比较的时候就一定要实现Comparator接口。另外,这两个接口是支持泛型的,所以我们应该在实现接口的同时定义比较类型。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值