当前位置: 首页 > article >正文

【JavaSE】java对象的比较

文章目录

  • 元素的比较
    • 基本类型的比较
    • 对象的比较
  • 如何进行对象比较
    • 重写`equals`方法
    • 基于`Comparble.compareTo`的比较
    • 基于`Comparator.compare`的比较
    • 区分`Comparator`和`Comparable`
  • 在`PriorityQueue`中比较的体现

元素的比较

基本类型的比较

Java中,基本类型可以直接进行大小的比较

        //1.基本元素的比较
        int a=10;
        int b=20;
        System.out.println(a>b);
        System.out.println(a<b);
        System.out.println(a==b);
        System.out.println("=============================");
        char ch1='A';
        char ch2='a';
        System.out.println(ch1==ch2);
        System.out.println(ch1>ch2);
        System.out.println(ch1<ch2);
        System.out.println("==========================");
        boolean b1=true;
        boolean b2=false;
        System.out.println(b1==b2);
        System.out.println(b1!=b2);

运行结果:
在这里插入图片描述

对象的比较

		//2.对象的比较
        Student s1=new Student();
        Student s2=new Student();
        Student s3=s2;
        System.out.println(s1==s2);
        //System.out.println(s1<s2);//编译报错
        System.out.println(s3==s2);

运行结果:
在这里插入图片描述

结论:Java的引用类型不能直接进行>或者<的比较.那么为什么可以进行==的比较呢?
因为:对于用户实现自定义类型,都默认继承自Object类,而Object类中提供了equals方法,而==默认情况下调用的就是equals方法.
equal的比较原则是:默认情况下,直接比较
引用变量的地址**

如何进行对象比较

重写equals方法

这里在Student类中重写equals方法

class Student{
    String name;//姓名
    Integer age;//年龄

    public Student(String name,Integer age){
          this.name=name;
          this.age=age;
    }
	//重写equals方法
    @Override
    public boolean equals(Object o) {
        
        if(o==null || !(o instanceof Student)) return false;

            Student obj=(Student)o;

            return this.name.equals(obj.name)?true:false;
    }

}
		//2.对象的比较
        Student s1=new Student("zhangsan",11);
        Student s2=new Student("zhangsan",12);

        Student s3=s2;
        System.out.println(s1==s2);
        System.out.println(s1.equals(s2));
        //System.out.println(s1<s2); ------编译报错
        System.out.println(s3==s2);

重写equals方法虽然可以进行比较,但是只能进行相等比较,不能按照大于,小于的方式进行比较

基于Comparble.compareTo的比较

在类的内部重写compareTo方法:

class Student implements Comparable<Student>{
    String name;//姓名
    Integer age;//年龄

    public Student(String name,Integer age){
          this.name=name;
          this.age=age;
    }
    
    @Override
    public int compareTo(Student o) {
        if(o==null) return 1;
        return age-o.age;
    }
}

进行比较:

public class CompareTest {
    public static void main(String[] args) {
    	Student s1=new Student("zhangsan",11);
        Student s2=new Student("lisi",16);
        Student s3=new Student("zhangsan",12);
		
		System.out.println(s1.compareTo(s2));
        System.out.println(s2.compareTo(s1));
        System.out.println(s3.compareTo(s2));
}
}

运行结果:
在这里插入图片描述

基于Comparator.compare的比较

在类的外部构造一个比较器Comparator:

/**
 * 在外部构造一个比较器
 * */
class StudentComparator implements Comparator<Student>{
    @Override
    public int compare(Student s1, Student s2) {
            return s1.age-s2.age;
    }
}
class Student implements Comparable<Student>{
    String name;//姓名
    Integer age;//年龄

    public Student(String name,Integer age){
          this.name=name;
          this.age=age;
    }
    
}    

调用比较器进行比较

		Student s1=new Student("zhangsan",11);
        Student s2=new Student("lisi",16);
        Student s3=new Student("zhangsan",12);
        //调用比较器
        StudentComparator stuComparator=new StudentComparator();
        System.out.println(stuComparator.compare(s1, s2));

运行结果:
在这里插入图片描述

区分ComparatorComparable

ComparatorComparable都是Java用于比较的对象,但它们的作用场景和使用方式有所不同:

  • Comparable接口:

    • 它是一个内置接口,通常由类自身实现,用于提供自定义类型的自然顺序。如果一个类实现了Comparable接口,那么它的实例就可以直接通过compareTo()方法与其他同类实例进行比较。比如,String类就是实现了Comparable<String>,可以直接比较两个字符串的大小。
    • 所以,Compareable接口需要手动实现,且代码的侵入性比较强,一旦实现,每次用该类都有顺序,属于内部顺序
  • Comparator接口:

    • 它是另一个独立于对象本身的接口,它允许你在运行时动态地改变比较规则。当需要对列表或其他集合进行排序,但不想修改类本身或者不知道对象内部如何排序时,可以使用Comparator
    • 需要实现一个比较器对象,对待比较类的侵入性弱.

PriorityQueue中比较的体现

由于PriorityQueue底层使用的堆结构,因此其内部的元素必须要能够比大小,PriorityQueue采用了两种比较方式的实现:

  • Comparable:是类默认的内部比较方式,如果用户插入自定义类型的对象时,该类对象必须要实现Comparable接口,并且重写了CompareTo方法
  • Comparator:用户也可以选择使用比较器对象,如果用户插入自定义类型对象时,必须要提供一个比较器类,让该类实现Comparator接口并且重写了compare方法

接下来我们通过源码来进行理解:
当我们进行插入操作时:

public boolean offer(E e) {
        if (e == null)
            throw new NullPointerException();
        modCount++;
        int i = size;
        if (i >= queue.length)
            grow(i + 1);
        siftUp(i, e);//向上调整
        size = i + 1;
        return true;
    }

这里我们看到,调用了关键方法siftUp向上调整方法.

private void siftUp(int k, E x) {
        if (comparator != null)
            siftUpUsingComparator(k, x, queue, comparator);
        else
            siftUpComparable(k, x, queue);
    }

在这里插入图片描述


http://www.kler.cn/a/377007.html

相关文章:

  • Linux:防火墙和selinux对服务的影响
  • Electron+Vue3+TS+sqlite3项目搭建加入sqlite3后无法运行问题
  • 沈阳乐晟睿浩科技有限公司抖音小店短视频时代的电商蓝海
  • ctfshow web入门文件上传总结
  • 【ShuQiHere】使用链表 (Linked List) 和数组 (Array) 实现栈 (Stack) 的深入解析与比较
  • 2. Flink快速上手
  • Web3中的数据主权:区块链如何为用户赋能
  • Java-02
  • VS2017+Qt5.12.9+CMake3.30.2编译VTK 9.2.0
  • 基于Springboot+Vue的养老系统(含源码数据库)
  • 数据结构与算法——第四讲:静态链表及双向链表
  • opencv 图像预处理
  • Unity humanoid 模型头发动画失效问题
  • YOLOv6-4.0部分代码阅读笔记-yolo_lite.py
  • 信源熵的概念
  • Java实现图片转pdf
  • ssm+jsp662教务信息平台的设计与实现
  • 如何将MySQL彻底卸载干净
  • 【MySQL】 运维篇—故障排除与性能调优:常见故障的排查与解决
  • STM32之串口字库更新