溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java中對象比較的示例分析

發(fā)布時間:2022-03-03 14:46:00 來源:億速云 閱讀:122 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹了Java中對象比較的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

    元素比較

    基本類型的比較

    在Java中,基本類型的對象可以直接比較大小

    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); 
       } 
    }

    對象的比較

    先來看一段代碼

    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); // 編譯報錯 
            System.out.println(c1 == c2);
            // 編譯成功 ----> 打印false,因?yàn)閏1和c2指向的是不同對象 
    
            //System.out.println(c1 < c2); // 編譯報錯 
            System.out.println(c1 == c3);
            // 編譯成功 ----> 打印true,因?yàn)閏1和c3指向的是同一個對象 
        }
    }

    c1、c2和c3分別是Card類型的引用變量,上述代碼在比較編譯時:

    c1 > c2 編譯失敗c1== c2 編譯成功c1 < c2 編譯失敗

    從編譯結(jié)果可以看出,Java中引用類型的變量不能直接按照 > 或者 < 方式進(jìn)行比較

    那為什么== 可以比較?

    因?yàn)椋?strong>對于用戶實(shí)現(xiàn)自定義類型,都默認(rèn)繼承自O(shè)bject類,而Object類中提供了equal方法,而 equal方法 在不覆寫的情況下,默認(rèn)用的就是 ==

    Java中對象比較的示例分析

    該方法的比較規(guī)則是:

    沒有比較引用變量引用對象的內(nèi)容,而是直接比較引用變量的地址

    但有些情況下用equals方法來比較就不符合題意。需要進(jìn)行覆寫,修改成我們所需要的比較方法

    對象如何進(jìn)行比較

    有些情況下,需要比較的是對象中的內(nèi)容,比如:

    向優(yōu)先級隊列中插入某個對象時,需要堆按照對象中內(nèi)容來調(diào)整堆,那該如何處理呢?

    以下提供三種比較對象的方式

    覆寫基類的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對象,或者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 的套路就是上面演示的

    • 如果指向同一個對象,返回 true

    • 如果傳入的為 null,返回 false

    • 如果傳入的對象類型不是 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)具體如下:

    Java中對象比較的示例分析

    對用用戶自定義類型,如果要想按照大小與方式進(jìn)行比較時:在定義類時,實(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接口源碼如下:

    Java中對象比較的示例分析

    按照比較器方式進(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, "?"); // 定義比較器對象 
            CardComparator cmptor = new CardComparator();
            // 使用比較器對象進(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 包中的泛型接口類,使用時必須導(dǎo)入對應(yīng)的包。

    三種比較方式對比

    覆寫的方法說明
    Object.equals因?yàn)樗蓄惗际抢^承自 Object 的,所以直接覆寫即可,不過只能比較相等與否
    Comparable.compareTo需要手動實(shí)現(xiàn)接口,侵入性比較強(qiáng),但一旦實(shí)現(xiàn),每次用該類都有順序,屬于內(nèi)部順序
    Comparator.compare需要實(shí)現(xiàn)一個比較器對象,對待比較類的侵入性弱,但對算法代碼實(shí)現(xiàn)侵入性強(qiáng)

    集合框架中PriorityQueue(優(yōu)先級隊列)的比較方式

    集合框架中的PriorityQueue底層使用堆結(jié)構(gòu),因此其內(nèi)部的元素必須要能夠比大小,PriorityQueue采用了:Comparble和Comparator兩種方式。

    Comparble是默認(rèn)的內(nèi)部比較方式,如果用戶插入自定義類型對象時,該類對象必須要實(shí)現(xiàn)Comparble接口,并覆寫compareTo方法

    用戶也可以選擇使用比較器對象,如果用戶插入自定義類型對象時必須要提供一個比較器類,讓該類實(shí)現(xiàn)Comparator接口并覆寫compare方法。

    Java中對象比較的示例分析

    感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Java中對象比較的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI