Java基础——比较器应用

本文详细介绍了Java中的比较器,包括自然排序和自定义排序的概念和实现方式。自然排序适用于实现了Comparator接口的类,而自定义排序则允许在不修改原有类的情况下提供排序规则。举例说明了如何根据学生成绩进行排序,并提到了ArrayList和PriorityQueue在比较器中的应用。

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

比较器

对象之间的比较

  • 自然排序:public interface Comparable<T>
  • 自定义排序:public interface Comparator<T>

自然排序

  • 对于实现了Comparable接口的类,都会实现public int compareTo(T o)方法(接口中只有这一个类)。
  • 不能和null比较,因为相比较的两者必须都是类对象
  • Javacore class除了java.math.BigDecimal这个类都默认实现了Comparable接口
  • 实现了Comparable接口的类的实例组成的数组可以通过CollectionsArrays中的sort()方法进行排序——对于实现该接口类的两个实例对象a1,a2:
    • 如果a1.compareTo(a2) == 0,那么表示二者相等;特别需要注意的是:通常情况下建议判等的结果应该和equals()结果一致
    • 如果a1.compareTo(a2) < 0返回小于0的整数,表示小于
    • 如果 a1.compareTo(a2)> 0返回大于0的整数,表示大于
  • 总之就是为了给排序函数提供一个比较大小的依据,需要进行排序的自定义类通过重写compareTo()方法将大小和正负零进行对应即可

自定义排序

  • 不是让待排序的类实现的,是作为形参使用的,所以不会影响原先实现的排序
  • Comparable接口不同的是除了抽象方法compare(T o1, T o2)之外还提供了很多默认方法
  • 当自定义类实现Comparable接口而又不方便修改代码, 或者实现了Comparable接口的排序规则不适合当前的操作,只是想在这异步操作中使用这排序规则,就可以用Comparator接口实现
  • 实现方法compare(T o1, T o2)有两个参数,表示相比较的两个元素,和Comparable接口中的compareTo(T o1)单参数(默认是thiso1相比)不同。
  • 返回值大小和正负零的对应和Comparable接口的实现一致
  • Comparator作为参数传递给 sort 方法(如 Collections.sort 或 Arrays.sort), 从而允许在排序顺序上实现调用时自定义

举例

自然排序

class Student implements Comparable{//实现Comparable接口的自定义类
    String name;
    int number;

    public Student() {
    }

    public Student(String name, int number) {
        this.name = name;
        this.number = number;
    }

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

    @Override
    public int compareTo(Object o) {//重写compareTo()方法,根据number变量排序
        if(o instanceof Student){
            Student stmp = (Student)o;
            if(this.number > ((Student) o).number)
                return 1;
            else if(this.number < ((Student) o).number)
                return -1;
            else
                return 0;
        }
        throw new RuntimeException("类型不匹配");
    }
}
public class CompareTest {
    public static void main(String[] args) {
        ArrayList<Student> arrayList = new ArrayList<>();
        Student s1 = new Student("Student1",1 );
        Student s2 = new Student("Student2",2 );
        Student s3 = new Student("Student3",3 );
        arrayList.add(s3);arrayList.add(s2);arrayList.add(s1);//逆序添加
        Collections.sort(arrayList);//排序,过程中会调用compareTo()方法
        for(Student s : arrayList)
            System.out.println(s);
    }
}

结果输出:
在这里插入图片描述
自定义排序
还是在上面例子中新增score成员变量,想在某次排序中根据学生的成绩进行排序而不用它默认的排序

class Student implements Comparable{
    String name;
    int number;
    int score;

    public Student() {
    }

    public Student(String name, int number,int score) {
        this.name = name;
        this.number = number;
        this.score = score;//新增score变量
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", number=" + number +
                ", score=" + score +
                '}';
    }

    @Override
    public int compareTo(Object o) {//注意这时候定义的自然排序还是保留
        if(o instanceof Student){
            Student stmp = (Student)o;
            if(this.number > ((Student) o).number)
                return 1;
            else if(this.number < ((Student) o).number)
                return -1;
            else
                return 0;
        }
        throw new RuntimeException("类型不匹配");
    }
}
public class CompareTest {
    public static void main(String[] args) {
        ArrayList<Student> arrayList = new ArrayList<>();
        Student s1 = new Student("Student1",1 ,69);
        Student s2 = new Student("Student2",2 ,85);
        Student s3 = new Student("Student3",3 ,60);
        arrayList.add(s3);arrayList.add(s2);arrayList.add(s1);//逆序添加
        Collections.sort(arrayList, new Comparator<Student>() {//自定义比较器实现成绩的倒序输出
            @Override
            public int compare(Student o1, Student o2) {
                if(o1.score < o2.score)
                    return 1;
                else if(o1.score > o2.score)
                    return -1;
                else
                    return 0;
            }
        });
        for(Student s : arrayList)
            System.out.println(s);
    }
}

结果输出
在这里插入图片描述
注意的是:按照通常意义上的大于小于相等对应正整数,负整数和零的话,排序结果就是从“小”到“大”,所以底层逻辑一定是按照返回值的负零正排序的;如果想要从“大”到“小”排序,就大于对等负数,以此类推

常用类中的体现

(正好做到一个相关优先队列的问题,翻看源码看到PriorityQueue中元素就是默认是按照自然排序排列(底层用的是二叉树小顶堆实现,不是链表)的(也可以自定义Comparator),但是不能用iterator对象遍历,poll()出才是排序后的结果)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值