“Java比较攻略:从基本类型到引用类型,一文读懂“

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏:数据结构(Java版) 

目录

基本数据类型的比较

引用数据类型的比较 

基于Comparble接口类的比较

基于比较器比较

三种方法的对比


基本数据类型的比较

像 int、char、double 这种基本数据类型,我们可以直接采用 == 来进行比较是否相等。

public class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = 10;
        System.out.println(a == b); // false
        System.out.println(a == c); // true
    }
}

这里的 == 是比较变量对应数据值。即 a == b,是看 10 == 20的结果如何,返回的是一个布尔类型的值:true 或者 false。

引用数据类型的比较 

对于 Integer、Double、Character 这种基本数据类型对应的引用数据类型,我们应该采用equals方法来进行比较。但是有的小伙伴可能对下面的代码会有疑惑:为什么同样是引用数据类型,结果的比较却不一样呢?不应该都是false吗?因为引用数据类型在用 == 进行比较时,是比较其两者的地址,因此都是false才对呀! 

public class Test {
    public static void main(String[] args) {
        Integer a = 10;
        Integer b = 20;
        Integer c = 10;
        System.out.println(a == b); // false
        System.out.println(a == c); // true

        Integer d = 1000;
        Integer e = 2000;
        Integer f = 1000;
        System.out.println(d == e); // false
        System.out.println(d == f); // false
    }
}

上面的理解是没有问题的。 引用数据类型在用 == 进行比较时,是比较其两者的地址,但是对于Integer类型的值来说,当Integer的类型的值在[-128,127]时,其地址都是相同的,因此 == 比较的结果也是一样的。

如果想了解其原理,可以去看这篇博客:数据结构之初始泛型-CSDN博客

因此,如果我们想要也和 == 一样是比较变量对应数据值的话,我们应该用equals方法

public class Test {
    public static void main(String[] args) {
        Integer a = 10;
        Integer b = 20;
        Integer c = 10;
        System.out.println(a.equals(b)); // false
        System.out.println(a.equals(c)); // true

        Integer d = 1000;
        Integer e = 2000;
        Integer f = 1000;
        System.out.println(d.equals(e)); // false
        System.out.println(d.equals(f)); // true

这里的equals方法只能用来比较两者是否相等,如果想要判断两个对象的大小关系就行不通了,并且 > 和 < 只能用来比较基本数据类型的大小,不能比较引用数据类型。还有我们自定义的类型比较是否相等的话,需要重写equals方法。

class Card {
    public String suit;
    public int rank;
    
    public Card(String suit, int rank) {
        this.suit = suit;
        this.rank = rank;
    }
}

这个Card类如果想要用equals方法来比较的话,得重写equals方法。这里可能有小伙伴会有疑惑: 这个类哪里来的equals方法?重写?继承了那个类?  所有类都是默认继承了Object类,而这个类中就有equals方法。但是Object类中的equals方法是下面这样的:

this 是指调用这个方法的对象。这里可以看出默认的equals方法解决不了问题。

    public boolean equals(Object o) {
        // 地址一样,返回true
        if (this == o) return true;
        // o为null或者两者类型不符,返回false
        if (o == null || getClass() != o.getClass()) return false;
        Card card = (Card) o;
        // int类型和String类型都相等才返回true,否则返回false
        return rank == card.rank && Objects.equals(suit, card.suit);
    }

一般覆写 equals 的套路就是上面这样:

 1. 如果指向同一个对象,返回 true;

2. 如果传入的为 null,返回 false;

3. 如果传入的对象类型不是 Card,返回 false;

4. 按照类的实现目标完成比较,例如这里只要花色和数值一样,就认为是相同的牌;

5. 注意调用其他引用类型的比较也需要 equals,例如这里的 suit 的比较。

覆写基类equal的方式虽然可以比较,但缺陷是:equal只能按照相等进行比较,不能按照大于、小于的方式进行比较。 因此下面就会介绍两者可以比较大小的方法。

基于Comparble接口类的比较

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

public interface Comparable<E> {
    // 返回值:
    // < 0: 表示 this 指向的对象小于 o 指向的对象
    // == 0: 表示 this 指向的对象等于 o 指向的对象
    // > 0: 表示 this 指向的对象大于 o 指向的对象
    int compareTo(E o);
}

comparble 主要是依赖于 compareTo方法进行大小的比较。

对用自定义类型,如果要想按照大小的方式进行比较,在定义类时,实现Comparble接口即可,然后在类中重写compareTo方法即可。

    @Override
    public int compareTo(Card o) {
        return this.rank - o.rank;
    }
    public static void main(String[] args) {
        Card card1 = new Card("♠", 5);
        Card card2 = new Card("♥",3);
        // card1 > card2  --> >0
        // card1 == card2 --> ==0
        // card1 < card2 --> <0
        System.out.println(card1.compareTo(card2)); // 2 > 0 --> card1 > card2
    }

基于比较器比较

按照比较器方式进行比较,具体步骤如下: 

1、用户自定义比较器类,实现Comparator接口;

2、重写Comparator中的compare方法即可。

class CardInCom implements Comparator<Card> {
    @Override
    public int compare(Card o1, Card o2) {
        return o1.rank - o2.rank;
    }
}
    public static void main(String[] args) {
        Card card1 = new Card("♠", 5);
        Card card2 = new Card("♥",3);
        CardInCom cardInCom = new CardInCom();
        System.out.println(cardInCom.compare(card1, card2)); // 2 --> card1 > card2
    }

三种方法的对比

重写的方法说明
Object.equalsObject.equals因为所有类都是继承自 Object 的,所以直接重写比较的规则即可,不过只能比较相等与否
Comparable.compareTo需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于内部顺序
Comparator.compare需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强

其实就是:重写equals只能比较想不想等, 想要比较大小得重写 Comparable.compareTo方法或者Comparator.compare方法;但是Comparator是一个比较器,只能在比较类的外部,Comparable是需要比较类实现接口,重写方法的。

好啦!本期 有关Java对象的比较 的学习之旅就到此结束啦!我们下一期再一起学习吧!

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我要学编程(ಥ_ಥ)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值