“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对象的比较 的学习之旅就到此结束啦!我们下一期再一起学习吧!
上一篇: python绘制爱心代码
下一篇: 【Python】成功解决Python报错:TypeError: __init__() got an unexpected keyword argument ‘n_iterations‘
本文标签
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。