JAVA学习日记(14)——java对象的比较

本文探讨了Java中对象比较的三种方式:基于equals、Comparable接口和Comparator接口。通过示例代码,解释了如何重写equals方法以进行对象相等比较,以及如何实现Comparable接口和Comparator接口进行对象的排序比较。最后,讨论了在集合框架PriorityQueue中的比较方式,并展示了如何解决Top-K问题。
摘要由CSDN通过智能技术生成

1.问题的提出

我们给定下面这样一段代码,拟定一副扑克牌,然后让它们之间进行比较

代码示例:

class Card {
	public int rank;//数值
	public String suit;//花色
	
	public Card (int rank,String suit) {
		this.rank = rank;
		this.suit =suit;
	}
}
public class TestDemo1 {
	public static void main(String[] args) {
        Card card1 = new Card(1,"♥");
        Card card2 = new Card(2,"♥");
        System.out.println(card1.equals(card2));
    }
}

之前在学习基本类型的时候,我们知道比较两个基本数据类型大小关系的时候,直接可以使用我们的运算符来(>,<,==)进行比较,但是对于我们上面的自定义类型来说,要比较 card1 和 card2 的大小关系我们可不可以直接用运算符来比较他们呢?

答案肯定是不行,因为我们知道 card1 和 card2 他们两个属于引用类型,按照我们人的思想来说 card2 肯定是大于 card1的,因为我们人的大脑通过比较两个牌的数值去判断它们的大小,但是在Java中我们直接使用大于或者小于号去比较编译器会直接报错,如果使用等于号去进行比较,那么比较的只是两个引用所保存的内存地址而已,那么我们应该怎么去进行比较呢?

我们可以回想一下之前在学习String类型的时候有一个方法叫作 equals 方法,那么我们现在试着用equals方法来对 card1和card2来进行比较

2.对象的比较

2.1 基于equals比较

public static void main(String[] args) {
        Card card1 = new Card(1,"♥");
        Card card2 = new Card(1,"♥");
        System.out.println(card1.equals(card2));
    }

我此时想要的结果是得到一个 true,但是真正当我们运行的时候,结果却是一个false,那么这是为什么呢?

false

我们先来定义两个字符串

String s1 = "hello";
String s2 = new String("hello");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));

我们肯定知道输出结果为 false 和 true,但是为什么刚刚在我们使用equals比较自定义类型的时候没有达到我们的预期结果,我们可以通过CTRL+鼠标左键点击String的equals方法来看看它到底是怎么实现的
在这里插入图片描述
我们可以看到String里面的equals方法它是通过将两个字符串拆成一个个字符来进行比较的,那么有的小伙伴可能会说,之所以我们自定义类型不能通过equals来进行比较是因为他们不是String类型,这种说法是错误的,我们也可以通过同样的方法来看看我们自定义类型使用的equals是什么样子
在这里插入图片描述
我们可以看到我们自定义类型所使用的equals方法是Object中的,它此时所比较的也是两个对象的引用,这也就是为什么我们会得到false的原因了,而我们已经知道我们所有的类都是默认继承于我们Object类,那么这也就是说,我们可以用过重写Object类中equals方法来为我们的自定义类型服务,具体我们可以借鉴String中重写的equals方法

代码示例:

@Override
    public boolean equals(Object obj) {
        //引用同一个对象
        if (this == obj) return true;
        //obj instanceof Card obj是否为Card的实例
        //obj可以是Card的子类,也可以是本身
        if (obj == null || !(obj instanceof Card)) return false;
        Card card = (Card) obj;
        if (this.rank == card.rank && this.suit.equals(card.suit)) {
            return true;
        }
        return false;
    }

现在我们再来运行刚刚的代码,就能得到我们想要的结果 true

true

因此我们可以总结出一点:如果自定义类型要进行equals比较的时候,必须要记得重写equals方法,当然在后面的学习里我们还要重写一个方法,具体在后面讲

2.2 基于Comparable接口类的比较

刚刚我们讲了通过重写equals方法来判断两个自定义类型是否相等,如果要进行大于小于的比较呢?我们之前讲过一个接口 Comparable,我们可以通过实现它来进行我们所需要的比较

代码示例:

class Card implements Comparable<Card> {
    public int rank;
    // 数值
    public String suit;
    // 花色
    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }

    //返回值等于0 相等
    //返回值大于0 this大
    //返回值小于0 o大
    @Override
    public int compareTo(Card o) {
        return this.rank - o.rank;
    }
}
public static void main(String[] args) {
    Card card1 = new Card(1,"♥");
    Card card2 = new Card(5,"♥");
    Card card3 = new Card(1,"♥")        	
    System.out.println(card1.compareTo(card2));
    System.out.println(card2.compareTo(card1));
    System.out.println(card1.compareTo(card3));
}

运行结果:

-4
4
0

此时大于就是返回一个大于0的数字,小于返回一个小于0的数字,等于就返回一个0

我们再自定义一个学生类

代码示例:

class Student {
    public int  age;
    public String name;
    public double score;

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

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", score=" 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值