• Java比较器之equals、comparable、comparator



    前言

    在Java中,基本类型的对象可以直接比较,而自定义类型,默认是用equal方法,但是它没有比较引用变量引用对象的内容,而是直接比较引用变量的地址,本文记录了解决该问题的几种方法。


    一、基本类型比较

    基本数据类型,一般可以使用==直接比较,字符串String类型可以使用equal进行比较。

    1.==

    作用:
    (1)用于基本数据类型的比较;
    (2)判断引用是否指向堆内存的同一块地址。

    2.equals

    作用:
    用于引用类型,在默认情况下,比较引用类型的内存地址是否相等;也可以根据需求,重写equals方法。

    Object类equals()方法源码:

    在这里插入图片描述

    String类equals()方法源码:
    在这里插入图片描述

    3.==和equals的区别

    对于引用类型,==会直接比较引用的地址,而用equals则比较的是引用的内容。
    在这里插入图片描述

    二、对象的比较

    1.覆写基类的equals

    缺点:equals只能按照相等进行比较,不能按照大于、小于的方式进行比较。
    如下重写equals方法,只能对年龄或者名字按照相等的方式比较。
    代码如下(示例):

    import java.util.Objects;
    
    class Student {
        public String name;
        public int age;
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return Objects.equals(name, student.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    }
    public class Demo {
        public static void main(String[] args) {
            Student s1 = new Student("王一", 20);
            Student s2 = new Student("金木", 19);
            System.out.println(s1.equals(s2));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    2.基于Comparable接口类的比较

    Comparable是jdk提供的泛型的比较接口类,源码实现具体如下:

    public interface Comparable<T> {
    	public int compareTo(T o);
    }
    
    • 1
    • 2
    • 3

    Comparable是java.lang中的接口类,可以直接使用。
    如下,自定义Student类,通过实现Comparable接口并重写compareTo方法,通过年龄对Student类的大小进行比较。

    import java.util.Objects;
    
    class Student implements Comparable<Student> {
        public String name;
        public int age;
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
        
        @Override
        public int compareTo(Student o) {
            if (o == null) return 1;
            return this.age - o.age;
        }
    }
    public class ComparatorDemo {
        public static void main(String[] args) {
            Student s3 = new Student("小王", 19);
            Student s4 = new Student("小刘", 22);
            System.out.println(s3.compareTo(s4)); //小于0 表示s3.age < s4.age
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3.基于Comparator比较器比较

    步骤:
    (1)用户自定义比较器类,实现Comparator接口;
    (2)覆写Comparator中的compare方法。

    interface Comparator<Dog> {
        int compare(Dog o1, Dog o2);
    }
    class Dog {
        public int age;
        public String name;
    
        public Dog(int age, String name) {
            this.age = age;
            this.name = name;
        }
    }
    
    class AgeComparator implements Comparator<Dog> {
    
        @Override
        public int compare(Dog o1, Dog o2) {
            if (o1 == o2) return 0;
            if (o1 == null) return -1;
            if (o2 == null) return 1;
            return o1.age - o2.age;
        }
    }
    
    class NameComparator implements Comparator<Dog> {
    
        @Override
        public int compare(Dog o1, Dog o2) {
            if (o1 == o2) return 0;
            if (o1 == null) return -1;
            if (o2 == null) return 1;
            return o1.name.compareTo(o2.name);
        }
    }
    public class ComparatorDemo {
        public static void main(String[] args) {
            Dog dog1 = new Dog(3, "aba");
            Dog dog2 = new Dog(2, "aaa");
            Dog dog3 = new Dog(3, "acd");
    
            //年龄比较器
            AgeComparator ageComparator = new AgeComparator();
    
            //名字比较器
            NameComparator nameComparator = new NameComparator();
    
            System.out.println(ageComparator.compare(dog1,dog2)); //>0,表示dog1.age > dog2.age
            System.out.println(nameComparator.compare(dog1, dog3)); //
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    4.三种方式对比

    覆写的方法说明
    Object.equals由于所有类都继承自Object,所以直接覆写即可,但只能比较相等与否
    Comparable.compareTo需要手动实现接口,侵入性较强,一旦实现,每次用该类都有顺序,属于内部顺序
    Comparator.compare需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强
  • 相关阅读:
    安徽身份证网上办理最全攻略
    MySQL XA事务文档翻译
    冯诺依曼体系结构及操作系统的认识
    (附源码)spring boot火车票订票系统 毕业设计 171538
    小黑跟中老黑和阿黄吃了烤蚕蛹知了,喝了阿黄带来的茅台,耳机又莫名其妙第丢了逐渐减少内耗的leetcode之旅:714. 买卖股票的最佳时机含手续费
    Linux crash调试(一)
    JavaScript-数组、函数
    最护眼的灯是白炽灯吗?专业的护眼台灯推荐
    sqlmap 攻击
    冒泡排序知识点
  • 原文地址:https://blog.csdn.net/qq_45283185/article/details/133160491