0
点赞
收藏
分享

微信扫一扫

Java基础之Comparable 和 Comparator 比较

惠特曼 2022-02-17 阅读 36

文章目录

Java 中 Comparable 和 Comparator 比较


Comparable 简介

Comparable 是排序接口。

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

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

Comparator 定义

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

package java.util;

public interface Comparator<T> {

    int compare(T o1, T o2);

    boolean equals(Object obj);
}

说明:

  • 若一个类要实现Comparator接口:它一定要重写compareTo(T o1, T o2) 函数,但可以不实现 equals(Object obj) 函数。

​ 为什么可以不实现 equals(Object obj) 函数呢? 因为任何类,默认都是已经实现了equals(Object obj)的。 Java中的一切类都是继承于java.lang.Object,在Object.java中实现了equals(Object obj)函数;所以,其它所有的类也相当于都实现了该函数。


Comparator 和 Comparable 区别

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

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

我们通过一个测试程序来对这两个接口进行说明。源码如下:

实现Comparable接口,重写compareTo

package wenhua.project;

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

/**
 * @author wenhua
 * @date 2022年02月17日 10:21
 */
public class Person implements Comparable<Person>{

    // 声明属性
    private int age ;
    private String name;

    // 生成构造方法
    public Person() {}

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

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

    /**
     * 实现Comparable接口,重写compareTo方法
     * @param person
     * @return
     */
    @Override
    public int compareTo(Person person) {
        // 实现类排序
        return name.compareTo(person.name);// 等价于return this.name - person.name;

    }

    public static void main(String[] args) {
        // 新建ArrayList(动态数组)
        ArrayList<Person> list = new ArrayList<Person>();
        // 添加对象到ArrayList中
        list.add(new Person(20,"ccc"));
        list.add(new Person(30,"AAA"));
        list.add(new Person(10,"bbb"));
        list.add(new Person(40,"ddd"));
       System.out.println("排序之前:"+list.toString());
        // 通过集合静态类Collections调用sort进行排序
        Collections.sort(list);
        System.out.println("排序之后:"+list.toString());

}

运行结果:

排序之前:[Person{age=20, name='ccc'}, Person{age=30, name='AAA'}, Person{age=10, name='bbb'}, Person{age=40, name='ddd'}]
排序之后:[Person{age=30, name='AAA'}, Person{age=10, name='bbb'}, Person{age=20, name='ccc'}, Person{age=40, name='ddd'}]

实现Comparator,重写compare方法

package wenhua.project;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author wenhua
 * @date 2022年02月17日 10:21
 */
public class Person implements Comparator<Person> {

    // 声明属性
    private int age ;
    private String name;

    // 生成构造方法
    public Person() {}
    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    // 生成get方法
    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

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

    /**
     * 实现Comparator接口,重写compare方法
     * @param o1
     * @param o2
     * @return
     */
    @Override
    public int compare(Person o1, Person o2) {
        // 升序
        return o1.getAge()-o2.getAge();
    }

    public static void main(String[] args) {
        // 指定比较器,对指定的对象数组进行排序
        Person[] list = new Person[4];
        list[0] = new Person(20,"ccc");
        list[1] = new Person(30,"AAA");
        list[2] = new Person(10,"bbb");
        list[3] = new Person(40,"ddd");
        // 注此时数组长度和存储数据长度一致,否则出现运行时错误:NullPointerException

        /* 方式一:
            创建实现了Comparator接口的子类Person(数组的数据类型)有排序功能,并重写其compare方法
        */
        Arrays.sort(list,new Person());
        System.out.println("方式一:升序输出:"+Arrays.toString(list));

        /* 方式二:
            直接实现Comparator接口创建匿名对象,重写compare方法
        */
        Arrays.sort(list,new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o2.getAge()-o1.getAge();// 降序
            }
        });
        System.out.println("方式二:降序输出:"+Arrays.toString(list));

    }

}

运行结果:

方式一:升序输出:[Person{age=10, name='bbb'}, Person{age=20, name='ccc'}, Person{age=30, name='AAA'}, Person{age=40, name='ddd'}]
方式二:降序输出:[Person{age=40, name='ddd'}, Person{age=30, name='AAA'}, Person{age=20, name='ccc'}, Person{age=10, name='bbb'}]

总结

Comparable接口直接实现且重写其compareTo方法,可直接通过Collections.sort(Object o)或Arrays.sort(Object o)方法调用,否则报错。
Comparator接口可以实现成一个排序类,在调用Arrays.sort()时必须传入new Comparator接口该对象(或子类该对象)的比较器。

参考文章:https://www.cnblogs.com/skywang12345/p/3324788.html

举报

相关推荐

0 条评论