Java中Comparable与Comparator的区别

本文详细介绍了Java中的排序机制,包括Comparable自然排序与Comparator定制排序的区别与应用。通过具体实例展示了如何实现这两个接口来对自定义类进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Comparable 简介

Comparable 是排序接口。在java.lang包下

若一个类实现了Comparable接口,就意味着“该类支持排序”。 即然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序。

此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中的元素,而不需要指定比较器。

Comparable 定义

Comparable 接口仅仅只包括一个函数,它的定义如下:
package java.lang;
import java.util.*;

public interface Comparable<T> 
{
    public int compareTo(T o);
}


说明: 
假设我们通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。

Comparator 简介

Comparator 是比较器接口。在java.util包下

我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可。

也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。

Comparator 定义

Comparator 接口仅仅只包括两个个函数,它的定义如下:

package java.util;

public interface Comparator<T> 
{

    int compare(T o1, T o2);

    boolean equals(Object obj);
}


Comparator 和 Comparable 比较

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

我们不难发现:Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。


代码演示:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
 * <em>测试类</em>
 * @author StormMaybin
 */
public class ComparatorAndComparableDemo 
{

    public static void main(String[] args) 
    {
        //定义一个ArrayList容器
        ArrayList<Person> persons = new ArrayList<Person>();
        String [] names = {"StormMa", "Jack", "Rose", "Mary"};
        int [] ages = {20, 21, 21, 18};
        for (int i = 0; i < 4; i++)
            persons.add(new Person(names[i], ages[i]));

        //排序之前
        System.out.println("排序之前: "+persons);


        //按照Person类中实现Comparable接口的规则排序。这里的规则是按照姓名排序
        Collections.sort(persons);
        System.out.println("按照姓名排序: "+persons);


        //通过AscAgeComparator比较器进行排序,即按照年龄升序排列
        Collections.sort(persons, new AscAgeComparator());
        System.out.println("按照年龄升序排序"+persons);


        //通过DscAgeComparator比较器进行排序,即按照年龄降序排列
        Collections.sort(persons, new DscAgeComparator());
        System.out.println("按照年龄降序排序"+persons);


        //通过AscAgeAscNameComparator比较器进行排序
        //即按照首先按照年龄升序,年龄相同的情况下,
        //按照姓名升序排列
        Collections.sort(persons, new AscAgeAscNameComparator());
        System.out.println("按照年龄和姓名升序排列: "+persons);
    }
}


/**
 * <em>Person类实现Comparable,按姓名升序排列</em>
 * @author StormMaybin
 */
class Person implements Comparable<Person>
{
    private String name;
    private int age;
    //Constructor
    public Person (String name, int age)
    {
        this.name = name;
        this.age = age;
    }
     /**
     * 比较两个Person是否相等:若它们的name和age都相等,则认为它们相等
     */
    boolean equals(Person o) 
    {
        if (this.age == o.age && this.name == o.name)
            return true;
        return false;
    }
    /**
     * 实现Comparable接口,这里只针对姓名进行排序
     */
    @Override
    public int compareTo(Person o) 
    {
        // TODO Auto-generated method stub
        return this.name.compareTo(o.name);
    }
    @Override
    public String toString() 
    {
        // TODO Auto-generated method stub
        return "( name: " + name +","+ "age: "+age+")";
    }
    public int getAge() 
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age = age;
    }
    public String getName() 
    {
        return name;
    }
    public void setName(String name) 
    {
        this.name = name;
    }
}

/**
 * <em>定义AscAgeComparator比较器实现Comparator接口
 * 对Person类的age属性进行升序排列</em>
 * @author StormMaybin
 */
class AscAgeComparator implements Comparator<Person>
{

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


/**
 * <em>定义DscAgeComparator比较器实现Comparator接口
 * 对Person类的age属性进行降序排列</em>
 * @author StormMaybin
 */
class DscAgeComparator implements Comparator<Person>
{

    @Override
    public int compare(Person o1, Person o2) 
    {
        // TODO Auto-generated method stub
        return -(o1.getAge() - o2.getAge());
    }
}
/**
 * <em>定义AscAgeAscNameComparator比较器实现Comparator接口
 * 对Person类的age name 属性升序排列</em>
 * @author StormMaybin
 */
class AscAgeAscNameComparator implements Comparator<Person>
{

    @Override
    public int compare(Person o1, Person o2) 
    {
        // TODO Auto-generated method stub
        if (o1.getAge() == o2.getAge())
            return o1.getName().compareTo(o2.getName());
        else
            return o1.getAge() - o2.getAge();
    }
}



运行结果:


总结:

Java 中的两种排序方式:

  1. Comparable 自然排序。(实体类实现)
  2. Comparator 是定制排序。(无法修改实体类时,直接在调用方创建)

同时存在时采用 Comparator(定制排序)的规则进行比较。

对于一些普通的数据类型(比如 String, Integer, Double…),它们默认实现了Comparable 接口,实现了 compareTo 方法,我们可以直接使用。

而对于一些自定义类,它们可能在不同情况下需要实现不同的比较策略,我们可以新创建 Comparator 接口,然后使用特定的 Comparator 实现进行比较。

换句话说,Comparable是让一个实体类具有排序的能力,而Comparator充当一个比较器的作用,不同实体类排序可以依据同一个比较器。

这就是 Comparable 和 Comparator 的区别。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值