Java中对象的比较

Java中对象的比较有三种方式

一:实现Compareable接口,重写compareTo方法(对类的侵入性太强)

class Student implements Comparable<Student>{
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    @Override
    public int compareTo(Student o) {
        return this.age-o.age;
    }
}

测试结果

public static void main(String[] args) {
        Student[] students = new Student[2];
        students[0] = new Student("shuo",23);
        students[1] = new Student("zhuo",13);
        Arrays.sort(students);
        // [Student@14ae5a5, Student@7f31245a]
        // 重写toString方法之后
        // [Student{name='zhuo', age=13}, Student{name='shuo', age=23}]
        System.out.println(Arrays.toString(students));
    }

二:使用Comparator,重写compare方法

// 按照年龄比较
class AgeComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getAge()-o2.getAge();
    }
}

// 按照姓名比较
class NameComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
    	// o1 是一个字符串 它自己有compareTo方法
        return o1.getName().compareTo(o2.getName());
    }
}

三:equals方法

  1. 基本类型与基本类型封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此Integer(0)会自动拆箱为int类型再进行比较,返回true
  2. 两个Integer类型进行“==”比较,如果其值在-128至127,那么返回true,否则返回false。这跟Integer.valueOf()的缓冲对象。
  3. 两个基本类型的封装型进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true
  4. 基本型封装类型调用equals(),但是参数是基本类型,这时候,会先进行自动装箱,基本型转换为其封装类型,在进行3中的比较。
int i = 189;
char d = 28;
Integer c = 189;
Integer j = new Integer(189);

System.out.println(i==j);//true
System.out.println(c==j);//false
System.out.println(j.equals(i));//true
System.out.println(c.equals(d));//false

使用equals,重写eauals方法

没有重写equals时,是直接用==判断的,而String中重写了equals方法。

public class TestWork {
    public String name = "abc";
    public static void main(String[] args) {
        TestWork test = new TestWork();
        TestWork testB = new TestWork();
        System.out.println(test.equals(testB)+","+test.name.equals(testB.name));
        // false,true
    }
}
@Override
    public boolean equals(Object o) {
        // 是不是两个引用指向同一个对象
        if (this == o) return true;
        // 如果传进来是一个null
        if (o == null) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

总结:三种比较方法的对比

重写的方法说明
Compare接口的compareTo方法需要手动实现接口,侵入性比较强,每次用该类都有顺序,属于内部顺序;Compareable接口将毕节哦代码嵌入自身类中;Comparable的比较方法compareTo只有一个参数;
Comparator接口的compare方法需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强;Comparator在一个独立的类中实现比较。Comparator接口的比较方法compare有两个参数;
重写Object的方法equals因为所有类都是继承自Object的,所以直接重写即可,不过只能比较相等与否

集合框架中PriorityQueue的比较方式

Alt+7 查看PriorityQueue的源码

offer方法的实现方式

如果是第一个元素,直接将插入的元素放到0下标,不存在比较。
不是第一个元素,发生向上调整。
在这里插入图片描述
siftUp方法的实现方式
向上调整使用了两个方案

  1. 用Compareator
  2. 用Comparable(默认)
    在这里插入图片描述

在这里插入图片描述
compare的第一个参数是插入的元素 x 是要插入的元素

不带参数的PriorityQueue方法
在这里插入图片描述

在这里插入图片描述

	public static void main(String[] args) {
        // 将比较器作为构造函数的参数传入
        // 可以控制 o1-o2 来控制大小堆
        PriorityQueue<Student> queue = new PriorityQueue<>(new AgeComparator());
        queue.offer(new Student("shuo",23));
        queue.offer(new Student("zhuo",13));
        // [Student{name='zhuo', age=13}, Student{name='shuo', age=23}]
        System.out.println(queue);
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值