亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

面試官讓你說(shuō)說(shuō)==和equals()的區(qū)別,重寫equals必須重寫hashcode方法嗎

1fe1se / 1740人閱讀

摘要:如果我們不重寫的方法,那么就會(huì)默認(rèn)調(diào)用的方法小王小王我們可以看到以上的運(yùn)行結(jié)果違背了的規(guī)定如果返回,那么方法必須返回相同的整數(shù)所以我們需要對(duì)對(duì)象的方法進(jìn)行重寫通過(guò)重寫讓其與對(duì)象的屬性關(guān)聯(lián)起來(lái),那么就能夠達(dá)到為,那么的值也相等。

面試官讓你說(shuō)說(shuō)==和equals()的區(qū)別,重寫equals必須重寫hashcode方法嗎

本身特質(zhì)來(lái)說(shuō)

==:操作符

equals():方法

適用對(duì)象

==:主要用于基本類型之間的比較(char、Boolean、byte、short、int、long、float、dobule),也可以用于比較對(duì)象

equals():對(duì)象之間的比較(基本類型的包裝器類型,string,自己定義的對(duì)象等)

比較對(duì)象時(shí)的區(qū)別

==:比較兩個(gè)對(duì)象是否指向同一個(gè)對(duì)象,也就是說(shuō)他們指向的對(duì)象的首地址是否相同

equals():可以通過(guò)重寫equals方法從而比較對(duì)象的內(nèi)容是否相同,如果不重寫那么和==符號(hào)沒(méi)有區(qū)別,都是比較的對(duì)象的引用是否指向同一個(gè)對(duì)象

對(duì)于一個(gè)對(duì)象student來(lái)說(shuō),如果我們不重寫它的equals方法,那么和==符號(hào)一樣比較的是對(duì)象的引用而不是內(nèi)容

public class Student {
    private int id;
    private String name;
    private String password;


    public Student(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

}
public class Test2 {
    public static void main(String[] args){

        Student s1 = new Student(1, "小王", "123456");
        Student s2 = new Student(1, "小王", "123456");
        System.out.println(s1 == s2);//false

        System.out.println(s1.equals(s2));//false
    }
}

上面兩個(gè)對(duì)象s1和s2不相等,因?yàn)樗麄冎赶虻氖莾蓚€(gè)不同的對(duì)象,所以引用不同,但是我們的目的是要達(dá)到如果id,name,password都相同,那么就是同一個(gè)對(duì)象,所以需要重寫equals()方法

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Student student = (Student) o;

    if (id != student.id) return false;
    if (name != null ? !name.equals(student.name) : student.name != null) return false;
    return password != null ? password.equals(student.password) : student.password == null;
}

這個(gè)時(shí)候我們?cè)龠\(yùn)行

public class Test2 {
    public static void main(String[] args){

        Student s1 = new Student(1, "小王", "123456");
        Student s2 = new Student(1, "小王", "123456");
        System.out.println(s1 == s2);//false
        System.out.println(s1.equals(s2));//true
    }
}

對(duì)于string類型來(lái)說(shuō),它的的equals()方法是對(duì)object方法的equals()進(jìn)行了重寫,從而比較的字符串序列是

否相同如下:

String s1 = new String("abc");//s1存在于堆內(nèi)存中
String s2 = new String("abc");//s2也存在于堆內(nèi)存中
System.out.println(s1 == s2);//false s1和s2指向的對(duì)象的首地址不一樣,不是同一個(gè)對(duì)象
System.out.println(s1.equals(s2));//true  s1和s2指向的對(duì)象的內(nèi)容相同

ps:

String s3 = "abc";
String s4 = "abc";
System.out.println(s3 == s4);//true 
System.out.println(s3.equals(s4));//true

接下來(lái)我們討論一下重寫equals()方法的同時(shí)必須要重寫hashcode()方法嗎

? 首先我們重寫equals()的目的就是為了讓內(nèi)容相同的對(duì)象讓它們相同,而不是單單只比較對(duì)象的引用(對(duì)象的首地址),也就是盡管這兩個(gè)對(duì)象的引用地址不同,但是我們調(diào)用equals方法的時(shí)候仍然返回true

? 那么這個(gè)時(shí)候我們?yōu)槭裁从忠貙慼ashcode方法呢,hashcode()返回的是對(duì)象的地址,是一個(gè)散列值,那么如果我們通過(guò)equals()方法得到這兩個(gè)對(duì)象相同,盡管他們?cè)诙阎械膬?nèi)存地址不一樣,但是我們希望他們的哈希值是一樣的,這樣如果存入map的話,就能定位到相同的索引

? 同時(shí)Java標(biāo)準(zhǔn)中對(duì)hashcode有如下的規(guī)定:

在java應(yīng)用程序執(zhí)行期間,如果在equals方法比較中所用的信息沒(méi)有被修改,那么在同一個(gè)對(duì)象上多次調(diào)用hashCode方法時(shí)必須一致地返回相同的整數(shù)。如果多次執(zhí)行同一個(gè)應(yīng)用時(shí),不要求該整數(shù)必須相同。

如果兩個(gè)對(duì)象通過(guò)調(diào)用equals方法是相等的,那么這兩個(gè)對(duì)象調(diào)用hashCode方法必須返回相同的整數(shù)。

如果兩個(gè)對(duì)象通過(guò)調(diào)用equals方法是不相等的,不要求這兩個(gè)對(duì)象調(diào)用hashCode方法必須返回不同的整數(shù)。

如果我們不重寫student的hashcode()方法,那么就會(huì)默認(rèn)調(diào)用object的hashcode()方法:

public class Test2 {
    public static void main(String[] args){

        Student s1 = new Student(1, "小王", "123456");
        Student s2 = new Student(1, "小王", "123456");
        System.out.println(s1 == s2);//false
        System.out.println(s1.equals(s2));//true
        System.out.println(s1.hashCode());//356573597
        System.out.println(s2.hashCode());//1735600054
    }
}

我們可以看到以上的運(yùn)行結(jié)果違背了hashcode的規(guī)定:如果equals()返回true,那么hashcode方法必須返回相同的整數(shù)

所以我們需要對(duì)student對(duì)象的hashcode方法進(jìn)行重寫

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

通過(guò)重寫hashcode()讓其與對(duì)象的屬性關(guān)聯(lián)起來(lái),那么就能夠達(dá)到equals()為true,那么hashcode的值也相等。

現(xiàn)在我們已經(jīng)知道了重寫equals()方法的同時(shí)需要重寫對(duì)象的hashcode()方法,讓其滿足hashcode的標(biāo)準(zhǔn)條件。

? 但是好奇的同學(xué)可能會(huì)想到:為什么hashcode需要這樣定義標(biāo)準(zhǔn)呢,這樣做到底有什么好處呢,除了讓equals()方法和hashcode()方法的返回值具有一致性。

這時(shí)我們就需要提到map類了,我們知道hashmap的結(jié)構(gòu)是一個(gè)數(shù)組加鏈表組成的,我們通過(guò)key的

? hashcode % hashmap的capacity 定位到具體數(shù)組的索引,然后將該(key,value)放入該索引對(duì)應(yīng)的鏈表里面,這里之所以為鏈表就是為了解決hash沖突,即hashcode % capacity 相同的值有很多,需要用一個(gè)鏈表存儲(chǔ)起來(lái),如果想要鏈表短一點(diǎn),也就是hash沖突少一點(diǎn),那么就需要減小hashmap的負(fù)載因子loadFacotor,當(dāng)然這里也就扯遠(yuǎn)了,我們繼續(xù)回到正題,

Student s1 = new Student(1, "小王", "123456");
Student s2 = new Student(1, "小王", "123456");

? 對(duì)于s1和s2兩個(gè)對(duì)象,如果我們我們已經(jīng)將s1存入一個(gè)map對(duì)象,那么我們?cè)俅嫒雜2時(shí),我們希望的是這是不能再插入map了,因?yàn)榇藭r(shí)map中已經(jīng)存在小王這個(gè)對(duì)象了,那么如何才能做到呢

? 首先我們通過(guò)s1的hashcode % capacity 得到了一個(gè)數(shù)組索引,然后將s1這個(gè)對(duì)象存入map,那么我們?cè)俨迦雜2的時(shí)候同樣也需要計(jì)算它的hashcode,然后定位到相同的數(shù)組索引,然后判斷該鏈表中是否存在小王這樣一個(gè)對(duì)象,如果存在就不put

? 所以我們需要得到的s1和s2的hashcode相同,才能避免同一個(gè)對(duì)象被put進(jìn)入map中多次,所以我們才需要在重寫equals()方法的同時(shí)重寫equals()方法,讓兩個(gè)相等的對(duì)象具有相同的hashcode

? 可能細(xì)心的盆友會(huì)發(fā)現(xiàn)如果我們只是需要簡(jiǎn)單的根據(jù)判斷兩個(gè)對(duì)象的內(nèi)容是否相同來(lái)判斷兩個(gè)對(duì)象是否相等,而不涉及到ma"p操作,那么其實(shí)也是不用重寫ha"shcode方法了,但是萬(wàn)一哪天突然不小心放進(jìn)了map了呢,所以一般我們重寫equals()方法的同時(shí)都會(huì)重寫hashcode(),確保萬(wàn)無(wú)一失~

參考

重寫equal()時(shí)為什么也得重寫hashCode()之深度解讀equal方法與hashCode方法淵源

重寫equals方法后重寫hashCode方法的必要性

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/77773.html

相關(guān)文章

  • 面試官:“你重寫過(guò) hashcode equals 么,為什么重寫equals時(shí)必須重寫hash

    摘要:介紹的作用是獲取哈希碼,也稱為散列碼它實(shí)際上是返回一個(gè)整數(shù)。所以具有相索引的對(duì)象,在該散列碼位置處存在多個(gè)對(duì)象,我們必須依靠的和本身來(lái)進(jìn)行區(qū)分。 1.hashCode介紹 hashCode() 的作用是獲取哈希碼,也稱為散列碼;它實(shí)際上是返回一個(gè)int整數(shù)。這個(gè)散列碼的作用是確定該對(duì)象在散列表中的索引位置,如果有看我的上一篇文章 什么是散列表,那么這里的散列碼就相當(dāng)于上文中根據(jù)首字母查...

    asce1885 評(píng)論0 收藏0
  • 【金三銀四】面試題之java基礎(chǔ)

    摘要:中,任何未處理的受檢查異常強(qiáng)制在子句中聲明。運(yùn)行時(shí)多態(tài)是面向?qū)ο笞罹璧臇|西,要實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)需要方法重寫子類繼承父類并重寫父類中已 1、簡(jiǎn)述Java程序編譯和運(yùn)行的過(guò)程:答:① Java編譯程序?qū)ava源程序翻譯為JVM可執(zhí)行代碼--字節(jié)碼,創(chuàng)建完源文件之后,程序會(huì)先被編譯成 .class 文件。② 在編譯好的java程序得到.class文件后,使用命令java 運(yùn)行這個(gè) .c...

    Yangyang 評(píng)論0 收藏0
  • 【金三銀四】面試題之java基礎(chǔ)

    摘要:中,任何未處理的受檢查異常強(qiáng)制在子句中聲明。運(yùn)行時(shí)多態(tài)是面向?qū)ο笞罹璧臇|西,要實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)需要方法重寫子類繼承父類并重寫父類中已 1、簡(jiǎn)述Java程序編譯和運(yùn)行的過(guò)程:答:① Java編譯程序?qū)ava源程序翻譯為JVM可執(zhí)行代碼--字節(jié)碼,創(chuàng)建完源文件之后,程序會(huì)先被編譯成 .class 文件。② 在編譯好的java程序得到.class文件后,使用命令java 運(yùn)行這個(gè) .c...

    Barrior 評(píng)論0 收藏0
  • Java知識(shí)體系之Java基礎(chǔ)

    摘要:最近看到上面的一篇博客面試必備最常見(jiàn)的面試題全解析講解了關(guān)于體系的一些模塊以及面試中的一些常見(jiàn)問(wèn)題雖然最近沒(méi)有要去找工作的需求但是鞏固一下這方面的知識(shí)還是很有必要的后面從作者提出的問(wèn)題進(jìn)行自我的提問(wèn)與解答有問(wèn)題歡迎大家指出基礎(chǔ)部分和的區(qū)別我 最近看到CSDN上面的一篇博客 面試必備:《Java最常見(jiàn)的200+面試題全解析》, 講解了關(guān)于Java體系的一些模塊以及面試中的一些常見(jiàn)問(wèn)題; ...

    zhou_you 評(píng)論0 收藏0
  • Java Object對(duì)象hashcodeequals方法

    摘要:在中對(duì)象是一切對(duì)象都會(huì)自動(dòng)繼承的一個(gè)類,在這個(gè)類中定義的屬性和方法可以說(shuō)是每個(gè)類都必須的。這里有必要說(shuō)說(shuō)這里對(duì)象里面的幾個(gè)方法返回該對(duì)象的哈希碼值。這些基于表的集合,只能要求被存放的對(duì)象實(shí)現(xiàn)自己的方法,保證的均勻性。 Object 在Java中Object對(duì)象是一切對(duì)象都會(huì)自動(dòng)繼承的一個(gè)類,在這個(gè)類中定義的屬性和方法可以說(shuō)是每個(gè)類都必須的。 這里有必要說(shuō)說(shuō)這里對(duì)象里面的幾個(gè)方法 has...

    chnmagnus 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<