欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Java 如何重寫(xiě)對象的 equals 方法和 hashCode 方法

前言:Java 對象如果要比較是否相等,則需要重寫(xiě) equals 方法,同時(shí)重寫(xiě) hashCode 方法,而且 hashCode 方法里面使用質(zhì)數 31。接下來(lái)看看各種為什么。

一、需求:

  對比兩個(gè)對象是否相等。對于下面的 User 對象,只需姓名和年齡相等則認為是同一個(gè)對象。

二、解決方案:

  需要重寫(xiě)對象的 equals 方法和 hashCode 方法

package com.yule.user.entity;import org.springframework.util.StringUtils;/** * 用戶(hù)實(shí)體 * * @author yule * @date 2018/8/6 21:51 */public class User {    private String id;    private String name;    private String age;    public User(){    }    public User(String id, String name, String age){        this.id = id;        this.name = name;        this.age = age;    }    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getAge() {        return age;    }    public void setAge(String age) {        this.age = age;    }    @Override    public String toString() {        return this.id + " " + this.name + " " + this.age;    }    @Override    public boolean equals(Object obj) {        if(this == obj){            return true;//地址相等        }        if(obj == null){            return false;//非空性:對于任意非空引用x,x.equals(null)應該返回false。        }        if(obj instanceof User){            User other = (User) obj;            //需要比較的字段相等,則這兩個(gè)對象相等            if(equalsStr(this.name, other.name)                    && equalsStr(this.age, other.age)){                return true;            }        }        return false;    }    private boolean equalsStr(String str1, String str2){        if(StringUtils.isEmpty(str1) && StringUtils.isEmpty(str2)){            return true;        }        if(!StringUtils.isEmpty(str1) && str1.equals(str2)){            return true;        }        return false;    }    @Override    public int hashCode() {        int result = 17;        result = 31 * result + (name == null ? 0 : name.hashCode());        result = 31 * result + (age == null ? 0 : age.hashCode());        return result;    }}

三、測試

  1、創(chuàng )建兩個(gè)對象,名字和年齡相等則對象 equals 為 true。

    @Test    public void testEqualsObj(){        User user1 = new User("1", "xiaohua", "14");        User user2 = new User("2", "xiaohua", "14");        System.out.println((user1.equals(user2)));//打印為 true    }

 四、為什么要重寫(xiě) equals 方法

  因為不重寫(xiě) equals 方法,執行 user1.equals(user2) 比較的就是兩個(gè)對象的地址(即 user1 == user2),肯定是不相等的,見(jiàn) Object 源碼:

    public boolean equals(Object obj) {        return (this == obj);    }

五、為什么要重寫(xiě) hashCode 方法

  既然比較兩個(gè)對象是否相等,使用的是 equals 方法,那么只要重寫(xiě)了 equals 方法就好了,干嘛又要重寫(xiě) hashCode 方法呢?

  其實(shí)當 equals 方法被重寫(xiě)時(shí),通常有必要重寫(xiě) hashCode 方法,以維護 hashCode 方法的常規協(xié)定,該協(xié)定聲明相等對象必須具有相等的哈希碼。那這又是為什么呢?看看下面這個(gè)例子就懂了。

  User 對象的 hashCode 方法如下,沒(méi)有重寫(xiě)父類(lèi)的 hashCode 方法

    @Override    public int hashCode() {        return super.hashCode();    }

  使用 hashSet

    @Test    public void testHashCodeObj(){        User user1 = new User("1", "xiaohua", "14");        User user2 = new User("2", "xiaohua", "14");        Set<User> userSet = new HashSet<>();        userSet.add(user1);        userSet.add(user2);        System.out.println(user1.equals(user2));        System.out.println(user1.hashCode() == user2.hashCode());        System.out.println(userSet);    }

  結果

  顯然,這不是我們要的結果,我們是希望兩個(gè)對象如果相等,那么在使用 hashSet 存儲時(shí)也能認為這兩個(gè)對象相等。

  通過(guò)看 hashSet 的 add 方法能夠得知 add 方法里面使用了對象的 hashCode 方法來(lái)判斷,所以我們需要重寫(xiě) hashCode 方法來(lái)達到我們想要的效果。

  將 hashCode 方法重寫(xiě)后,執行上面結果為

    @Override    public int hashCode() {        int result = 17;        result = 31 * result + (name == null ? 0 : name.hashCode());        result = 31 * result + (age == null ? 0 : age.hashCode());        return result;    }

  所以:hashCode 是用于散列數據的快速存取,如利用 HashSet/HashMap/Hashtable 類(lèi)來(lái)存儲數據時(shí),都會(huì )根據存儲對象的 hashCode 值來(lái)進(jìn)行判斷是否相同的。

六、如何重寫(xiě) hashCode

  生成一個(gè) int 類(lèi)型的變量 result,并且初始化一個(gè)值,比如17

  對類(lèi)中每一個(gè)重要字段,也就是影響對象的值的字段,也就是 equals 方法里有比較的字段,進(jìn)行以下操作:a. 計算這個(gè)字段的值 filedHashValue = filed.hashCode(); b. 執行 result = 31 * result + filedHashValue;

七、為什么要使用 31

  看一看 String hashCode 方法的源碼:

    /**     * Returns a hash code for this string. The hash code for a     * {@code String} object is computed as     * <blockquote><pre>     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]     * </pre></blockquote>     * using {@code int} arithmetic, where {@code s[i]} is the     * <i>i</i>th character of the string, {@code n} is the length of     * the string, and {@code ^} indicates exponentiation.     * (The hash value of the empty string is zero.)     *     * @return  a hash code value for this object.     */    public int hashCode() {        int h = hash;        if (h == 0 && value.length > 0) {            char val[] = value;            for (int i = 0; i < value.length; i++) {                h = 31 * h + val[i];            }            hash = h;        }        return h;    }

  可以從注釋看出:空字符串的 hashCode 方法返回是 0。并且注釋中也給了個(gè)公式,可以了解了解。

  String 源碼中也使用的 31,然后網(wǎng)上說(shuō)有這兩點(diǎn)原因:

原因一:更少的乘積結果沖突

  31是質(zhì)子數中一個(gè)“不大不小”的存在,如果你使用的是一個(gè)如2的較小質(zhì)數,那么得出的乘積會(huì )在一個(gè)很小的范圍,很容易造成哈希值的沖突。而如果選擇一個(gè)100以上的質(zhì)數,得出的哈希值會(huì )超出int的最大范圍,這兩種都不合適。而如果對超過(guò) 50,000 個(gè)英文單詞(由兩個(gè)不同版本的 Unix 字典合并而成)進(jìn)行 hash code 運算,并使用常數 31, 33, 37, 39 和 41 作為乘子,每個(gè)常數算出的哈希值沖突數都小于7個(gè)(國外大神做的測試),那么這幾個(gè)數就被作為生成hashCode值得備選乘數了。

  所以從 31,33,37,39 等中間選擇了 31 的原因看原因二。

原因二:31 可以被 JVM 優(yōu)化

  JVM里最有效的計算方式就是進(jìn)行位運算了:

  * 左移 << : 左邊的最高位丟棄,右邊補全0(把 << 左邊的數據*2的移動(dòng)次冪)。
  * 右移 >> : 把>>左邊的數據/2的移動(dòng)次冪。
  * 無(wú)符號右移 >>> : 無(wú)論最高位是0還是1,左邊補齊0。   

       所以 : 31 * i = (i << 5) - i(左邊  31*2=62,右邊   2*2^5-2=62) - 兩邊相等,JVM就可以高效的進(jìn)行計算啦。。。

 

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
淺析equals()與hashCode()方法的重寫(xiě)
轉 Java中equals()和hasCode()的方法詳解_NightMare
Java Set集合的詳解
java中HashSet詳解
equals方法和hashCode方法詳解
(1)正確重寫(xiě)hashCode的辦法
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久