中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Java中hashCode()和equals()的用法

發布時間:2021-06-21 09:05:53 來源:億速云 閱讀:179 作者:chen 欄目:開發技術

這篇文章主要講解了“Java中hashCode()和equals()的用法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java中hashCode()和equals()的用法”吧!

寫在前面

其實很早我就注意到阿里巴巴Java開發規范有一句話:只要重寫 equals,就必須重寫 hashCode

Java中hashCode()和equals()的用法

我想很多人都會問為什么,所謂知其然知其所以然,對待知識不單止知道結論還得知道原因。

hashCode方法

hashCode()方法的作用是獲取哈希碼,返回的是一個int整數

Java中hashCode()和equals()的用法

學過數據結構的都知道,哈希碼的作用是確定對象在哈希表的索引下標。比如HashSet和HashMap就是使用了hashCode方法確定索引下標。如果兩個對象返回的hashCode相同,就被稱為“哈希沖突”。

equals方法

equals()方法的作用很簡單,就是判斷兩個對象是否相等,equals()方法是定義在Object類中,而所有的類的父類都是Object,所以如果不重寫equals方法則會調用Object類的equals方法。

Java中hashCode()和equals()的用法

Object類的equals方法是用“”號進行比較,在很多時候,因為號比較的是兩個對象的內存地址而不是實際的值,所以不是很符合業務要求。所以很多時候我們需要重寫equals方法,去比較對象中每一個成員變量的值是否相等。

問題來了

重寫equals()方法就可以比較兩個對象是否相等,為什么還要重寫hashcode()方法呢?

因為HashSet、HashMap底層在添加元素時,會先判斷對象的hashCode是否相等,如果hashCode相等才會用equals()方法比較是否相等。換句話說,HashSet和HashMap在判斷兩個元素是否相等時,會先判斷hashCode,如果兩個對象的hashCode不同則必定不相等

Java中hashCode()和equals()的用法

下面我們做一個試驗,有一個User類,只重寫equals()方法,然后放到Set集合中去重。

public class User {

    private String id;

    private String name;

    private Integer age;
    
    public User(String id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id) &&
            Objects.equals(name, user.name) &&
            Objects.equals(age, user.age);
    }
    
    //getter、setter、toString方法
}

然后我們循環創建10個成員變量的值都是一樣的User對象,最后放到Set集合中去重。

public static void main(String[] args) {
    List<User> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        User user = new User("1", "張三", 18);
        list.add(user);
    }
    Set<User> set = new HashSet<>(list);
    for (User user : set) {
        System.out.println(user);
    }
    List<User> users = list.stream().distinct().collect(Collectors.toList());
    System.out.println(users);
}

按道理我們預期會去重,只剩下一個“張三”的user,但實際上因為沒有重寫hashCode方法,所以沒有去重。

Java中hashCode()和equals()的用法

接著我們在User類里面重寫一些hashCode方法再試試,其他不變。

public class User {
    //其他不變
    
    //重寫hashCode方法
    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
}

再運行,結果正確。

Java中hashCode()和equals()的用法

究其原因在于HashSet會先判斷hashCode是否相等,如果hashCode不相等就直接認為兩個對象不相等,不會再用equals()比較了。我們不妨看看重寫hashCode方法和不重寫hashCode方法的哈希碼。

這是不重寫hashCode方法的情況,每個user對象的哈希碼都不一樣,所以HashSet會認為都不相等。

Java中hashCode()和equals()的用法

這是重寫hashCode方法的情況,因為是用對象所有的成員變量的值計算出的哈希碼,所以只要兩個對象的成員變量都是相等的,則生成的哈希碼是相同的。

Java中hashCode()和equals()的用法

那么有些人看到這里,就會問,如果兩個對象返回的哈希碼都是一樣的話,是不是就一定相等

答案是不一定的,因為HashSet、HashMap判斷哈希碼相等后還會再用equals()方法判斷。

總而言之:

  • 哈希碼不相等,則兩個對象一定不相同。

  • 哈希碼相等,兩個對象不一定相同。

  • 兩個對象相同,則哈希碼和值都一定相等。

總結

所以回到開頭講的那句,只要重寫 equals,就必須重寫 hashCode,這是一個很重要的細節,如果不注意的話,很容易發生業務上的錯誤。

感謝各位的閱讀,以上就是“Java中hashCode()和equals()的用法”的內容了,經過本文的學習后,相信大家對Java中hashCode()和equals()的用法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

社会| 芦山县| 铅山县| 海南省| 革吉县| 思茅市| 开阳县| 济宁市| 罗甸县| 肥城市| 丰镇市| 三穗县| 萝北县| 景德镇市| 泽库县| 兰溪市| 镇巴县| 锡林浩特市| 开封县| 巫山县| 安塞县| 乌什县| 彭阳县| 依兰县| 汤阴县| 张家界市| 仙桃市| 松滋市| 义马市| 永善县| 梁山县| 互助| 邳州市| 阿尔山市| 孙吴县| 福海县| 文山县| 许昌市| 永宁县| 资溪县| 洛南县|