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

CSDN 2024-09-07 11:05:03 阅读 93

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

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

所属专栏:JavaSE

目录

基本数据类型的比较

引用数据类型的比较 

基于Comparble接口类的比较

基于比较器比较

三种方法的对比


基本数据类型的比较

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

<code>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方法解决不了问题。

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

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

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



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。