摘要:上面的程序輸出的結(jié)果是兩個(gè)。使用包重寫和方法包提供了兩個(gè)非常優(yōu)秀的類來生成和方法。需要注意記住的事情盡量保證使用對(duì)象的同一個(gè)屬性來生成和兩個(gè)方法。方法必須保證一致如果對(duì)象沒有被修改,應(yīng)該返回相同的值任何時(shí)候只要那么必須和相等。
hashCode()方法被用來獲取給定對(duì)象的唯一整數(shù),這個(gè)整數(shù)被用來確定對(duì)象被存儲(chǔ)在HashTable類似的結(jié)構(gòu)中的位置,Object類的hashCode()方法返回這個(gè)對(duì)象存儲(chǔ)的內(nèi)存地址的編號(hào)。
equal()相等的兩個(gè)對(duì)象他們的hashCode()肯定相等 hashCode()相等的兩個(gè)對(duì)象他們的equal()不一定相等
對(duì)比的時(shí)候
首先用hashCode()去對(duì)比,如果hashCode()不一樣,則表示這兩個(gè)對(duì)象肯定不相等 如果hashCode()相同,此時(shí)再對(duì)比他們的equal(),如果equal()也相同,則表示這兩個(gè)對(duì)象是真的相同了
這樣的好處
hash散列算法,使得在hash表中查找一個(gè)記錄速度變O(1).每個(gè)記錄都有自己的hashcode,散列算法按照hashcode把記錄放置在合適的位置.在查找一個(gè)記錄,首先先通過hashcode快速定位記錄的位置.然后再通過equals來比較是否相等.沒有hashcode,一個(gè)一個(gè)比較過來,時(shí)間就變O(N)了
這種大量的并且快速的對(duì)象對(duì)比一般使用的hash容器中,比如hashset,hashmap,hashtable等等,比如hashset里要求對(duì)象不能重復(fù),則他內(nèi)部必然要對(duì)添加進(jìn)去的每個(gè)對(duì)象進(jìn)行對(duì)比,而他的對(duì)比規(guī)則就是像上面說的那樣,先hashCode(),如果hashCode()相同,再用equal()驗(yàn)證,如果hashCode()都不同,則肯定不同,這樣對(duì)比的效率就很高了
然而hashCode()和equal()一樣都是基本類Object里的方法,而和equal()一樣,Object里hashCode()里面只是返回當(dāng)前對(duì)象的地址,如果是這樣的話,那么我們相同的一個(gè)類,new兩個(gè)對(duì)象,由于他們?cè)趦?nèi)存里的地址不同,則他們的hashCode()不同,所以這顯然不是我們想要的,所以我們必須重寫我們類的hashCode()方法
public class Employee { private Integer id; private String firstname; private String lastName; private String department; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } } public class EqualsTest { public static void main(String[] args) { Employee e1 = new Employee(); Employee e2 = new Employee(); e1.setId(100); e2.setId(100); //Prints false in console System.out.println(e1.equals(e2)); } }
毫無疑問,上面的程序?qū)⑤敵鰂alse
我們需要重寫equals方法
public boolean equals(Object o) { if(o == null) { return false; } if (o == this) { return true; } if (getClass() != o.getClass()) { return false; } Employee e = (Employee) o; return (this.getId() == e.getId()); }
在上面的類中添加這個(gè)方法,EauqlsTest將會(huì)輸出true。
import java.util.HashSet; import java.util.Set; public class EqualsTest { public static void main(String[] args) { Employee e1 = new Employee(); Employee e2 = new Employee(); e1.setId(100); e2.setId(100); //Prints "true" System.out.println(e1.equals(e2)); Setemployees = new HashSet (); employees.add(e1); employees.add(e2); //Prints two objects System.out.println(employees); } }
上面的程序輸出的結(jié)果是兩個(gè)。如果兩個(gè)employee對(duì)象equals返回true,Set中應(yīng)該只存儲(chǔ)一個(gè)對(duì)象才對(duì),問題在哪里呢?
我們忘掉了第二個(gè)重要的方法hashCode()。就像JDK的Javadoc中所說的一樣,如果重寫equals()方法必須要重寫hashCode()方法。我們加上下面這個(gè)方法,程序?qū)?zhí)行正確。
@Override public int hashCode() { final int PRIME = 31; int result = 1; result = PRIME * result + getId(); return result; }
使用Apache Commons Lang包重寫hashCode() 和equals()方法
Apache Commons 包提供了兩個(gè)非常優(yōu)秀的類來生成hashCode()和equals()方法??聪旅娴某绦?。
import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; public class Employee { private Integer id; private String firstname; private String lastName; private String department; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } @Override public int hashCode() { final int PRIME = 31; return new HashCodeBuilder(getId()%2==0?getId()+1:getId(), PRIME). toHashCode(); } @Override public boolean equals(Object o) { if (o == null) return false; if (o == this) return true; if (o.getClass() != getClass()) return false; Employee e = (Employee) o; return new EqualsBuilder(). append(getId(), e.getId()). isEquals(); } }
如果你使用Eclipse或者其他的IDE,IDE也可能會(huì)提供生成良好的hashCode()方法和equals()方法。
需要注意記住的事情
盡量保證使用對(duì)象的同一個(gè)屬性來生成hashCode()和equals()兩個(gè)方法。在我們的案例中,我們使用員工id。
eqauls方法必須保證一致(如果對(duì)象沒有被修改,equals應(yīng)該返回相同的值)
任何時(shí)候只要a.equals(b),那么a.hashCode()必須和b.hashCode()相等。
兩者必須同時(shí)重寫。
當(dāng)使用ORM的時(shí)候特別要注意的
如果你使用ORM處理一些對(duì)象的話,你要確保在hashCode()和equals()對(duì)象中使用getter和setter而不是直接引用成員變量。因?yàn)樵贠RM中有的時(shí)候成員變量會(huì)被延時(shí)加載,這些變量只有當(dāng)getter方法被調(diào)用的時(shí)候才真正可用。
例如在我們的例子中,如果我們使用e1.id == e2.id則可能會(huì)出現(xiàn)這個(gè)問題,但是我們使用e1.getId() == e2.getId()就不會(huì)出現(xiàn)這個(gè)問題。
文章引用:https://www.oschina.net/quest...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/71688.html
摘要:它也是用來判斷兩個(gè)對(duì)象是否相等,所以也得分不同的情況來說明。什么是的作用是獲取哈希碼,也稱為散列碼它返回的一個(gè)整數(shù)。這個(gè)哈希碼的作用是確定該對(duì)象在哈希表中的索引位置。它定義在的中,這就意味著中的任何類都包含有函數(shù)。 前言 萬丈高樓平地起,今天的聊點(diǎn)基礎(chǔ)而又經(jīng)常讓人忽視的話題,比如==與equals()區(qū)別?為何當(dāng)我們重寫完equals()后也要有必要去重寫hashcode()呢? .....
摘要:方法提供了對(duì)象的值,是一個(gè)方法,返回的默認(rèn)值與一致。通常這個(gè)值是對(duì)象頭部的一部分二進(jìn)制位組成的數(shù)字,具有一定的標(biāo)識(shí)對(duì)象的意義存在,但絕不定于地址。與的關(guān)系相等兩個(gè)對(duì)象,則一定要相等。 Java基礎(chǔ)系列 Java的hashcode與equals方法 Java類初始化順序 ThreadPoolExecutor線程池如何彈性伸縮 HashMap的幾個(gè)要點(diǎn) Integer的緩存 什么場(chǎng)景下使...
摘要:在中對(duì)象是一切對(duì)象都會(huì)自動(dòng)繼承的一個(gè)類,在這個(gè)類中定義的屬性和方法可以說是每個(gè)類都必須的。這里有必要說說這里對(duì)象里面的幾個(gè)方法返回該對(duì)象的哈希碼值。這些基于表的集合,只能要求被存放的對(duì)象實(shí)現(xiàn)自己的方法,保證的均勻性。 Object 在Java中Object對(duì)象是一切對(duì)象都會(huì)自動(dòng)繼承的一個(gè)類,在這個(gè)類中定義的屬性和方法可以說是每個(gè)類都必須的。 這里有必要說說這里對(duì)象里面的幾個(gè)方法 has...
摘要:地址面試必備最最最常見的面試題總結(jié)第一周一中的值傳遞和引用傳遞非常重要首先要明確的是對(duì)象傳遞數(shù)組類接口是引用傳遞,原始類型數(shù)據(jù)整型浮點(diǎn)型字符型布爾型傳遞是值傳遞。這個(gè)哈希碼的作用是確定該對(duì)象在哈希表中的索引位置。 showImg(https://segmentfault.com/img/remote/1460000015923339?w=922&h=519); 這里會(huì)分享一些出現(xiàn)頻率極...
摘要:不同的對(duì)象,建議有不同的。所以最好是讓均勻的落在不同的。正確寫法如下要對(duì)兩個(gè)字段做聯(lián)合去重時(shí)皮一下做,做,放入結(jié)果可能為這種情況就是違反了第條,放入了不同的。 我的第一篇文章 以前都在公司的文檔里寫,后來想想,還是自己找個(gè)地方記錄下來吧。今天有個(gè)朋友問我hashcode的問題,記錄下來,并稍微讀下書尋求一點(diǎn)理論知識(shí)。問題如下有一個(gè)屬性都是字符串的對(duì)象,想放入hashset中,要求,對(duì)某...
閱讀 3241·2021-11-22 09:34
閱讀 2872·2021-09-22 15:28
閱讀 884·2021-09-10 10:51
閱讀 1905·2019-08-30 14:22
閱讀 2400·2019-08-30 14:17
閱讀 2813·2019-08-30 11:01
閱讀 2377·2019-08-29 17:19
閱讀 3723·2019-08-29 13:17