【java接口】Comparable接口和Comparator接口

Comparable接口(类内部实现)

当排序基本数据类型和非自定义的引用类型时,我们通常会调用Arrays.sort(Object o)方法进行比较,实际上,引用类型(String、Integer等)能够调用上述方法,是因为该类已经实现了Comparable接口中的compareTo()方法,所以可以非常方便的比较。下面是Integer包装类实现Comparable接口中compareTo方法的源代码:

public int compareTo(Integer anotherInteger) {
    int thisVal = this.value;
    int anotherVal = anotherInteger.value;
    return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}

但是当我们想要比较自己定义的引用类型时,该怎么办呢?比如想要让Employee类的集合对象List<Employee> es = new ArrayList<Employee>(); 按照工资的高低排序,能够直接调用Arrays.sort(es)吗?答案当然是:NO!

让一个类使用排序服务必须让它实现Comparable类的compareTo方法。因为要向sort方法提供对象的比较方式。但是为什么不能在Employee类直接提供一个compareTo方法,而必须实现Comparable接口呢?
理由:java程序设计语言是一种强类型语言。在调用方法的时候,编译器将会检查这个方法是否存在。在sort方法中有这样的语句

// Insertion sort on smallest arrays
if (length < INSERTIONSORT_THRESHOLD) {
    for (int i=low; i<high; i++)
        for (int j=i; j>low && ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
            swap(dest, j, j-1);
    return;
}

因此编译器必须确认dest[j-1]有compareTo方法。如果dest是一个Comparable对象的数组,就可以确保拥有compareTo方法,因为每一个实现comparable接口的类必须提供这个方法的实现方式。

package comparable;

public class People2 implements Comparable<People2>{
    private String name;
    private double salary;
    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public People2(String name, double salary) {
        super();
        this.name = name;
        this.salary = salary;
    }

    public void setName(String name) {
        this.name = name;
    }

    public People2(String name) {
        super();
        this.name = name;
    }

    @Override
    public String toString() {
        return "People2 [name=" + name + " salary=" + salary + "]";
    }

    @Override
    public int compareTo(People2 o) {
        // TODO Auto-generated method stub
        return Double.compare(this.salary, o.salary);
    }

}
package comparable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class People2Test {
    public static void main(String[] args){
        List<People2> p = new ArrayList<People2>();

        People2 p1  = new People2("a",1);
        People2 p2 = new People2("bbb",2222); 
        People2 p3 = new People2("bbbss",333);
        p.add(p1);
        p.add(p2);
        p.add(p3);
        //Collections类的sort方法可以进行排序,List类型的只能使用该类的排序方法,不可以使用Arrays类的sort
        Collections.sort(p);

        for(People2 cur: p)
            System.out.println(cur);

    }

}

Comparator接口(类外部实现)

对一个对象数组进行排序,就可以应用上述方法来实现。但是如果想要改变已有的排序方法,如想要更改String类的的compareTo方法的功能。现有的String.compareTo方法是可以按照字典的顺序比较字符串。但是如果想要按照字符串长度递增的顺序排序字符串该怎么办呢?

  • 第一步:准备要排序的数组
  • 第二步:实现Comparator接口的compare方法

下面显示Comparator接口的源码:

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

想要哪找长度比较字符串,可以定义一个实现Comparator接口的compare类

public class LengthComparator implements Comparator<String>{

    @Override
    public int compare(String o1, String o2) {
        // TODO Auto-generated method stub
        return o1.length() - o2.length();
    }   

    public static void main(String[] args){
        Comparator<String> p  = new LengthComparator();

        String[] s = {"fujie","cuidapanger","xiaocui"};
        String[] ss = {"fujie","cuidapanger","xiaocui"};
        Arrays.sort(s);
        //输出结果
        //cuidapanger
        //fujie
        //xiaocui
        for(String cur: s){
            System.out.println(cur);
        }

        //第一个参数是:要排序的对象;第二个参数:是实现Comparator接口的类的实例,通过它调用更改后的compare方法
        Arrays.sort(ss, p); 
        //输出结果
        //fujie
        //xiaocui
        //cuidapanger
        for(String cur: ss){
            System.out.println(cur);
        }
    }
}

总结

Comparable的使用

一个类实现Comparable接口就表明这个类的对象之间是可以进行相互比较的,这个类对象组成的集合就可以调用Collections类的sort方法进行比较

Comparator的使用

情况一:实体类本身没有实现Comparable方法,但是又希望比较类对象,那这个时候就可以使用Comparator接口,通过实现该接口的compare方法来实现排序功能。简言之:实体类还是实体类,排序交给比较器Comparator实现类
情况二:想要String类不仅可以按照字典顺序排序,还可以按照字符串长度排序时就可以用比较器Comparator。情况见上述代码。因此可以使用比较器为一个类提供多种比较的方式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值