[Java学习] Comparator和Comparable的区别


前言

最近在学习Java的基础语法,遇见了Comparator和Comparable两个用于比较的接口,特地记录一下,方便以后复习应用。本人作为新手,第一次写文章,如有错误欢迎指正。


一、Comparable

1.1 Comparable简介

Comparable为java.lang包下的排序接口。Arrars类中的sort方法承诺可以对对象数组进行排序,但需要满足下面的条件:对象所属的类必须实现Comparable接口。

Comparable接口的代码如下:

public interface Comparable {
	int compareTo(Object other)
}

这说明,任何实现Comparable接口的类都需要包含compareTo方法,这个方法有一个Object参数,并且返回一个整数。

1.2 代码实例

首先定义一个Employee类实现Comparable接口,代码如下:

public class Employee implements Comparable<Employee>{
    private String name;
    private double salary;

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

    public String getName() {
        return name;
    }

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

    public double getSalary() {
        return salary;
    }

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

    public void raiseSalary(double byPercent){
        double raise=salary*byPercent/100;
        salary+=raise;
    }

    /**
     * Compares employees by salary
     * @param o
     * @return
     */
    @Override
    public int compareTo(Employee o) {
        return Double.compare(salary, o.salary);
    }
}

利用生成的类,在test类中直接使用Array.sort方法对类中元素进行排序(此时排序的对象是员工的薪水)。测试类代码如下:

public class ComparableTest {
    public static void main(String[] args) {
        var staff=new Employee[3];
        staff[0]=new Employee("Harry Hacker",35000);
        staff[1]=new Employee("Carl Cracker",75000);
        staff[2]=new Employee("Tony Tester",30000);

        Arrays.sort(staff);
        for(Employee e:staff){
            System.out.println("name="+e.getName()+",salary="+e.getSalary());
        }
    }
}

最终得到下面的结果:

name=Tony Tester,salary=30000.0
name=Harry Hacker,salary=35000.0
name=Carl Cracker,salary=75000.0

二、Comparator

2.1 Comparator简介

Comparator是比较接口,如果我们需要控制某个类的次序。而该类并没有实现Comparable接口,这是我们只需要定义一个比较器实现Comparator接口即可。

还有一种情况。例如,可以对一个字符串数组排序,因为String类实现了Comparable接口,而且String.compareTo方法可以按字典顺序比较字符串。而如果我们希望按长度递增的顺序对字符串进行排序,而不是按字典顺序进行排序。这时,我们不能让String类去用两种不同的方式来实现compareTo方法,更何况我们也不能去修改String类,这时我们就需要定义一个比较器去实现Comparator。

下面为Comparator接口的代码:

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

首先,定义一个Student类,不实现任何接口:

public class Students {
    private String name;
    private int no;

    public Students() {
    }

    public Students(String name, int no) {
        this.name = name;
        this.no = no;
    }

    public String getName() {
        return name;
    }

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

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    @Override
    public String toString() {
        return "Students{" +
                "name='" + name + '\'' +
                ", no=" + no +
                '}';
    }
}

下面为测试类:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * 用Comparator排序
 */
public class ComparatorTest {
    public static void main(String[] args) {
        ArrayList<Students> arrayList=new ArrayList<>();
        arrayList.add(new Students("zhangsan",200112));
        arrayList.add(new Students("lisi",200222));
        arrayList.add(new Students("wangwu",389890));
        arrayList.add(new Students("zhaoliu",467368));

        Collections.sort(arrayList,new Comparator<Students>(){

            @Override
            public int compare(Students o1, Students o2) {
                return o2.getNo()-o1.getNo();
            }
        });
        for(Students s:arrayList){
            System.out.println("学生的学号倒序:"+s.getNo());
        }
    }
}

这里利用了匿名内部类的方法,实现了一个比较器,完成了学生学号降序排列的功能。
其中,compare(int o1, int o2)方法 return o1 - o2 是升序,return o2 - o1 是降序。

最终实现结果如下:

学生的学号倒序:467368
学生的学号倒序:389890
学生的学号倒序:200222
学生的学号倒序:200112

总结

Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”。而Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。

两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值