认识比较器

这篇具有很好参考价值的文章主要介绍了认识比较器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Java中比较器是排序、加入有序数组等操作的时候必须要有的,没有的话会报错,例如下面这段代码:

package dataStructure.heap;

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

public class MyComparatorTest {
    public static void main(String[] args) {
        Student[] students = {new Student(2, "student2", 20),
                new Student(2, "student3", 30), new Student(4, "student4", 40)};
        //这里如果只写students数组而不传入比较器的话会报错

        Arrays.sort(students);
       
    }
}

class Student {
    int age;
    String name;
    int id;

    public Student(int age, String name, int id) {
        this.age = age;
        this.name = name;
        this.id = id;
    }
    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;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

}

运行时会发生下面的异常

Exception in thread "main" java.lang.ClassCastException: dataStructure.heap.Student cannot be cast to java.lang.Comparable
    at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
    at java.util.Arrays.sort(Arrays.java:1246)
    at dataStructure.heap.MyComparatorTest.main(MyComparatorTest.java:13)

Process finished with exit code 1

这个sort方法是可以只传入数组(数组中的类型是基础类型或者已经实现了Comparable了),也可以传入两个参数:数组和数组中类型的比较器

比较器实现有两种方式,

一种是当前类实现了java.lang.Comparable接口,这个时候当前类需要实现下面这个方法:

@Override
public int compareTo(Object o) {
    return 0;
}

这种方式只有一种比较方式,比较死板,一般我不会使用(虽然也可以叠加比较器,叠加比较器的时候相当于这是一种默认的,传了使用比较器,没有传使用这个)

第二种方式是:写一个比较器类继承Comparator,范型是当前类型(也可以不写比较器类而在使用的时候直接传入Lambda表达式)

改造之后的类如下:

package dataStructure.heap;

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

public class MyComparatorTest {
    public static void main(String[] args) {
        Student[] students = {new Student(2, "student2", 20),
                new Student(2, "student3", 30), new Student(4, "student4", 40)};
        //这里如果只写students数组而不传入比较器的话会报错
        //第二个参数是比较器类或者Lambda表达式
        Arrays.sort(students, new AgeAscComparator());
        Arrays.sort(students, (a, b) -> a.age - b.age);
        for (Student student : students) {
            System.out.println(student);
        }
        
    }
}

class AgeAscIdDescComparator implements  Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age == o2.age ? o2.id - o1.id : o1.age - o2.age;
    }
}

class AgeAscComparator implements Comparator<Student> {

    //这个是必须实现的方法,所有的比较器都需要遵循以下规律:
    //1.返回负数的时候,认为第一个参数应该排在前面,例如数字类型的谁小谁在前
    //2.返回正数的时候,认为第二个参数应该排在前面,例如数字类型的谁大谁在前
    //3.返回0的时候,无所谓谁排在前面
    @Override
    public int compare(Student o1, Student o2) {
        /**
         * 这一句话也可以替换为:if(o1.age < o2.age) {
         *  return -1;
         * } else if(o1.age > o2.age) {
         *  return 1;
         * } else {
         *  return 0;
         *  }
         */
        return o1.age - o2.age;
    }
}

class Student {
    int age;
    String name;
    int id;

    public Student(int age, String name, int id) {
        this.age = age;
        this.name = name;
        this.id = id;
    }
    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;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

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

运行结果:

Student{age=2, name='student2', id=20}
Student{age=2, name='student3', id=30}
Student{age=4, name='student4', id=40}

Process finished with exit code 0

这里我们看到其实age排序并不能明确区分student2还是student3在前

使用第二种方式写更复杂一点的比较器类(多个字段比较或者同一个字段相同的时候区别先后顺序)

class AgeAscIdDescComparator implements  Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        //如果age相同,按id降序
        //如果age不同,按age升序
        return o1.age == o2.age ? o2.id - o1.id : o1.age - o2.age;
    }
}

传入这个比较器的时候运行结果如下(确定age相同的时候id大的在前):

Student{age=2, name='student3', id=30}
Student{age=2, name='student2', id=20}
Student{age=4, name='student4', id=40}文章来源地址https://www.toymoban.com/news/detail-424776.html

到了这里,关于认识比较器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#使用自定义的比较器对版本号(编码)字符串进行排序

    给定一些数据,如下所示: “1.10.1.1.1.2”, “1.1”, “2.2”, “1.1.1.1”, “1.1.3.1”, “1.1.1”, “2.10.1.1.1”, “1.1.2.1”, “1.2.1.1”, “2.5.1.1”, “1.10.1.1”, “1.10.2.1”, “1.11.3.1”, “1.11.12.1”, “1.11.11.1”, “1.11.3.1”, “1”, “1.1.1.1.1”, “1.1.1.1.1.1” 实现效果: 按照每个节点层

    2024年02月11日
    浏览(32)
  • 使用java.lang.Comparable实现比较器和使用java.util.Collections排序

    记录 :469 场景 :使用java.lang.Comparable实现比较器,使用java.util.Collections排序,实现找出最大值。 版本 :JDK 1.8,Spring Boot 2.6.3,fastjson-2.0.33。 1.一个JSON字符串,找出最大值 1.1JSON字符串 1.2解析 把JSON字符串转换是JSONArray类型,把值取出转换为独立对象,再做比较。 2.使用java.

    2024年02月15日
    浏览(30)
  • Java ---比较器

          我们知道基本数据类型的数据(除 boolean 类型外)需要比较大小的话,之间使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢?      在 Java 中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比

    2024年02月03日
    浏览(30)
  • 8.2 电压比较器(1)

    电压比较器是对输入信号进行鉴幅与比较的电路,是组成非正弦波发生电路的基本单元电路,在测量和控制中有着相当广泛的应用。 1、电压比较器的电压传输特性 电压比较器的输出电压 u O u_{scriptscriptstyle O} u O ​ 与输入电压 u I u_{scriptscriptstyle I} u I ​ 的函数关系 u O = f

    2024年02月11日
    浏览(35)
  • 一位比较器【模电实验】

    一位比较器,数值比较器的作用和原理是什么? 一、数值比较器的定义及功能 在数字系统中,特别是在计算机中都具有运算功能,一种简单的运算就是比较两个数A和B的大小。数值比较器就是对两数A、B进行比较,以判断其大小的逻辑电路。比较结果有A>B、A<B以及

    2024年02月05日
    浏览(50)
  • LM393电压比较器介绍

    概述       LM393 是双电压比较器集成电路。主要应用在脉冲发生器、模数转换器、限幅器、数字逻辑门电路、电压比较电路等场合。LM393电压比较器能直接连接TTL和CMOS电平电路。 特点 1、工作温度范围:0℃ --- +70℃; 2、工作电源电压范围宽,单电源、双电源均可工作:    

    2024年02月03日
    浏览(53)
  • JAVA语言-比较器Comparator

    目录 一、什么是Comparator 二、Java compare方法和compareTo方法 三、java中Comparable和Comparator的区别 Comparator的例子 Comparator 是javase中的接口,位于java.util包下。 数组工具类和集合工具类中提供的工具方法sort方法都给出了含有Comparator接口的重载方法。 List实例调sort方法 demo如下: 使

    2024年02月06日
    浏览(30)
  • Java比较器(Comparator接口)

    1.当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序 2.重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回

    2024年02月15日
    浏览(33)
  • Verilog | 4位数值比较器

    牛客上的一道题,记录一下 这道题有两种思路: 第一种是按位比较,列举出所有情况: 第二种方法是,使用同或的方式获取一个标志位,进而获得判断依据: 关于比较器还有另外一道题 问题描述 给定8个数,以及若干二输入的比较器(可以将两个输入排序)。要求在单周期

    2024年02月11日
    浏览(24)
  • LM324电压比较器介绍

    LM324 电压比较器简介       LM324 是单电源四路运算放大器,是一个具有差分输入和单端输出的高增益电压放大器。与在单电源应用场合的标准运算放大器比起来,其优点更明显。该四路放大器可以工作于低至3.0 V或高达32 V的电源电压,静态电流是MC1741的五分之一左右(每个放

    2024年02月06日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包