Java數(shù)據(jù)結(jié)構(gòu)之對(duì)象的比較
??元素比較
??基本類型的比較
在Java中,基本類型的對(duì)象可以直接比較大小
public class TestCompare {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a > b);
System.out.println(a < b);
System.out.println(a == b);
char c1 = 'A'; char c2 = 'B';
System.out.println(c1 > c2);
System.out.println(c1 < c2);
System.out.println(c1 == c2);
boolean b1 = true; boolean b2 = false;
System.out.println(b1 == b2);
System.out.println(b1 != b2);
}
}
??對(duì)象的比較
先來看一段代碼
class Card {
public int rank; // 數(shù)值
public String suit; // 花色
public Card(int rank, String suit) {
this.rank = rank;
this.suit = suit;
}
}
public class TestPriorityQueue {
public static void main(String[] args) {
Card c1 = new Card(1, "?");
Card c2 = new Card(2, "?");
Card c3 = c1;
//System.out.println(c1 > c2); // 編譯報(bào)錯(cuò)
System.out.println(c1 == c2);
// 編譯成功 ----> 打印false,因?yàn)閏1和c2指向的是不同對(duì)象
//System.out.println(c1 < c2); // 編譯報(bào)錯(cuò)
System.out.println(c1 == c3);
// 編譯成功 ----> 打印true,因?yàn)閏1和c3指向的是同一個(gè)對(duì)象
}
}
c1、c2和c3分別是Card類型的引用變量,上述代碼在比較編譯時(shí):
c1 > c2 編譯失敗c1== c2 編譯成功c1 < c2 編譯失敗
從編譯結(jié)果可以看出,Java中引用類型的變量不能直接按照 > 或者 < 方式進(jìn)行比較。
那為什么== 可以比較?
因?yàn)椋?strong>對(duì)于用戶實(shí)現(xiàn)自定義類型,都默認(rèn)繼承自O(shè)bject類,而Object類中提供了equal方法,而 equal方法 在不覆寫的情況下,默認(rèn)用的就是 ==

該方法的比較規(guī)則是:
沒有比較引用變量引用對(duì)象的內(nèi)容,而是直接比較引用變量的地址
但有些情況下用equals方法來比較就不符合題意。需要進(jìn)行覆寫,修改成我們所需要的比較方法
??對(duì)象如何進(jìn)行比較
有些情況下,需要比較的是對(duì)象中的內(nèi)容,比如:
向優(yōu)先級(jí)隊(duì)列中插入某個(gè)對(duì)象時(shí),需要堆按照對(duì)象中內(nèi)容來調(diào)整堆,那該如何處理呢?
以下提供三種比較對(duì)象的方式
??覆寫基類的equal
public class Card {
public int rank; // 數(shù)值
public String suit; // 花色
public Card(int rank, String suit) {
this.rank = rank; this.suit = suit;
}
@Override public boolean equals(Object o) {
// 自己和自己比較
if (this == o) {
return true;
}
// o如果是null對(duì)象,或者o不是Card的子類
if (o == null || !(o instanceof Card)) {
return false;
}// 注意基本類型可以直接比較,但引用類型最好調(diào)用其equal方法
Card c = (Card)o;
return rank == c.rank && suit.equals(c.suit);
}
}
注意: 一般覆寫 equals 的套路就是上面演示的
- 如果指向同一個(gè)對(duì)象,返回 true
- 如果傳入的為 null,返回 false
- 如果傳入的對(duì)象類型不是 Card,返回 false
- 按照類的實(shí)現(xiàn)目標(biāo)完成比較,例如這里只要花色和數(shù)值一樣,就認(rèn)為是相同的牌
- 注意下調(diào)用其他引用類型的比較也需要 equals,例如這里的 suit 的比較
覆寫基類equal的方式雖然可以比較,但缺陷是:equal只能按照相等進(jìn)行比較,不能按照大于、小于的方式進(jìn)行比較。
??基于Comparble接口類的比較
Comparble是JDK提供的泛型的比較接口類,源碼實(shí)現(xiàn)具體如下:

對(duì)用用戶自定義類型,如果要想按照大小與方式進(jìn)行比較時(shí):在定義類時(shí),實(shí)現(xiàn)Comparble接口即可,然后在類中重寫compareTo方法。
public class Card implements Comparable<Card> {
public int rank; // 數(shù)值
public String suit; // 花色
public Card(int rank, String suit) {
this.rank = rank;
this.suit = suit;
}
// 根據(jù)數(shù)值比較,不管花色
// 這里我們認(rèn)為 null 是最小的
@Override
public int compareTo(Card o) {
if (o == null) {
return 1;
}
return rank - o.rank;
}
public static void main(String[] args) {
Card p = new Card(1, "?");
Card q = new Card(2, "?");
Card o = new Card(1, "?");
System.out.println(p.compareTo(o));
// == 0,表示牌相等 System.out.println(p.compareTo(q));
// < 0,表示 p 比較小 System.out.println(q.compareTo(p));
// > 0,表示 q 比較大
}
}
Compareble是java.lang中的接口類,可以直接使用
??基于比較器的比較
Comparator接口源碼如下:

按照比較器方式進(jìn)行比較,具體步驟如下:
用戶自定義比較器類,實(shí)現(xiàn)Comparator接口
class CardComparator implements Comparator<Card> {
// 根據(jù)數(shù)值比較,不管花色
// 這里我們認(rèn)為 null 是最小的
********************
//覆寫代碼區(qū)
********************
}
注意:區(qū)分Comparable和Comparator。
覆寫Comparator中的compare方法
@Override
public int compare(Card o1, Card o2) {
if (o1 == o2) {
return 0;
}
if (o1 == null) {
return -1;
}
if (o2 == null) {
return 1;
}
return o1.rank - o2.rank;
}
調(diào)用自定義的比較器
public static void main(String[] args){
Card p = new Card(1, "?");
Card q = new Card(2, "?");
Card o = new Card(1, "?"); // 定義比較器對(duì)象
CardComparator cmptor = new CardComparator();
// 使用比較器對(duì)象進(jìn)行比較
System.out.println(cmptor.compare(p, o)); // == 0,表示牌相等
System.out.println(cmptor.compare(p, q)); // < 0,表示 p 比較小
System.out.println(cmptor.compare(q, p)); // > 0,表示 q 比較大
}
注意:Comparator是java.util 包中的泛型接口類,使用時(shí)必須導(dǎo)入對(duì)應(yīng)的包。
??三種比較方式對(duì)比
| 覆寫的方法 | 說明 |
|---|---|
| Object.equals | 因?yàn)樗蓄惗际抢^承自 Object 的,所以直接覆寫即可,不過只能比較相等與否 |
| Comparable.compareTo | 需要手動(dòng)實(shí)現(xiàn)接口,侵入性比較強(qiáng),但一旦實(shí)現(xiàn),每次用該類都有順序,屬于內(nèi)部順序 |
| Comparator.compare | 需要實(shí)現(xiàn)一個(gè)比較器對(duì)象,對(duì)待比較類的侵入性弱,但對(duì)算法代碼實(shí)現(xiàn)侵入性強(qiáng) |
??集合框架中PriorityQueue(優(yōu)先級(jí)隊(duì)列)的比較方式
集合框架中的PriorityQueue底層使用堆結(jié)構(gòu),因此其內(nèi)部的元素必須要能夠比大小,PriorityQueue采用了:Comparble和Comparator兩種方式。
Comparble是默認(rèn)的內(nèi)部比較方式,如果用戶插入自定義類型對(duì)象時(shí),該類對(duì)象必須要實(shí)現(xiàn)Comparble接口,并覆寫compareTo方法
用戶也可以選擇使用比較器對(duì)象,如果用戶插入自定義類型對(duì)象時(shí),必須要提供一個(gè)比較器類,讓該類實(shí)現(xiàn)Comparator接口并覆寫compare方法。

總結(jié)
到此這篇關(guān)于Java數(shù)據(jù)結(jié)構(gòu)之對(duì)象比較的文章就介紹到這了,更多相關(guān)Java對(duì)象的比較內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringCloud?LoadBalancerClient?負(fù)載均衡原理解析
LoadBalancerClient?是?SpringCloud?提供的一種負(fù)載均衡客戶端,Ribbon?負(fù)載均衡組件內(nèi)部也是集成了?LoadBalancerClient?來實(shí)現(xiàn)負(fù)載均衡,本文給大家深入解析?LoadBalancerClient?接口源碼,感興趣的朋友跟隨小編一起看看吧2022-02-02
淺談SpringMVC的攔截器(Interceptor)和Servlet 的過濾器(Filter)的區(qū)別與聯(lián)系 及Spr
這篇文章主要介紹了淺談SpringMVC的攔截器(Interceptor)和Servlet 的過濾器(Filter)的區(qū)別與聯(lián)系 及SpringMVC 的配置文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
MyBatis實(shí)現(xiàn)插入大量數(shù)據(jù)方法詳解
最近在公司項(xiàng)目開發(fā)中遇到批量數(shù)據(jù)插入或者更新,下面這篇文章主要給大家介紹了關(guān)于MyBatis實(shí)現(xiàn)批量插入的相關(guān)資料,需要的朋友可以參考下2022-11-11
idea中java及java web項(xiàng)目的常見問題及解決
在IDEA中處理亂碼問題主要涉及四個(gè)方面:文件編碼設(shè)置為UTF-8、編輯器默認(rèn)編碼調(diào)整、Tomcat運(yùn)行配置編碼設(shè)置以及解決cmd中的亂碼,此外,詳細(xì)介紹了在IDEA中創(chuàng)建Web項(xiàng)目的步驟,包括新建Java工程、添加Web框架支持、添加Tomcat依賴庫(kù)2024-09-09
Spring中ApplicationListener的使用解析
這篇文章主要介紹了Spring中ApplicationListener的使用解析,ApplicationContext事件機(jī)制是觀察者設(shè)計(jì)模式的實(shí)現(xiàn),通過ApplicationEvent類和ApplicationListener接口,需要的朋友可以參考下2023-12-12
如何批量測(cè)試Mybatis項(xiàng)目中的Sql是否正確詳解
這篇文章主要給大家介紹了關(guān)于如何批量測(cè)試Mybatis項(xiàng)目中Sql是否正確的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12
Mybatis Criteria使用and和or進(jìn)行聯(lián)合條件查詢的操作方法
這篇文章主要介紹了Mybatis Criteria的and和or進(jìn)行聯(lián)合條件查詢的方法,本文通過例子給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10

