日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 哈希码

發(fā)布時間:2024/1/1 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 哈希码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

哈希碼(HashCode)

哈希碼產生的依據(jù):哈希碼并不是完全唯一的,它是一種算法,讓同一個類的對象按照自己不同的特征盡量的有不同的哈希碼,但不表示不同的對象哈希碼完全不同。也有相同的情況,看程序員如何寫哈希碼的算法。

什么是哈希碼(HashCode)

在Java中,哈希碼代表對象的特征。 例如對象 String str1 = “aa”, str1.hashCode= 3104 String str2 = “bb”, str2.hashCode= 3106 String str3 = “aa”, str3.hashCode= 3104 根據(jù)HashCode由此可得出str1!=str2,str1==str3 下面給出幾個常用的哈希碼的算法。 1:Object類的hashCode.返回對象的內存地址經(jīng)過處理后的結構,由于每個對象的內存地址都不一樣,所以哈希碼也不一樣。 2:String類的hashCode.根據(jù)String類包含的字符串的內容,根據(jù)一種特殊算法返回哈希碼,只要字符串所在的堆空間相同,返回的哈希碼也相同。 3:Integer類,返回的哈希碼就是Integer對象里所包含的那個整數(shù)的數(shù)值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。由此可見,2個一樣大小的Integer對象,返回的哈希碼也一樣。

equals方法在hibernate中的應用。

equals方法是默認的判斷2個對象是否相等的方法,在Object類里有實現(xiàn),判斷的是2個對象的內存地址。在hibernate中,不允許存在同類對象中有2個一樣的實例。hibernate通過equals方法做判斷。如: User u1 = new User(“張三”); User u2 = new User(“李四”); User u3 = new User(“張三”); 按照項目需求,用戶只要名字相同,就表示同一個用戶,所以我們認為,u1和u3是同一個人,同一個對象。但是因為u1,u2,u3三者的內存地址都各不相同,所以hibernate會認為這是3個不同的對象。這與我們假設的出了矛盾。 因此,我們將覆蓋Object類中的equals方法。 public class User{ private String userName; ….//get ,set方法省 //覆蓋Object里的equals方法 public boolean equals(Object arg0){ if (!(arg0 instanceof User)){ return false; } User user = (User)arg0; //如果名字相同,則表示屬于同一個對象。 if(user.getName().equals(this.getName)){ return true; }else{ return false; } } 這樣hibernate在插入數(shù)據(jù)的時候,如果傳過來一個叫”張三”的用戶,hibernate會先判斷有沒有叫“張三”的用戶,如果沒有,就允許插入,如果有,就不允許插入。這樣做可以保證數(shù)據(jù)的高度一致性,不同的項目有不同的需求,所以要根據(jù)自己的需求來覆蓋equals方法。

equals和HashCode的關系

在hibernate中,它認為2個對象只要equals返回true,那么hashCode一定相等。 但是實際情況呢? User u1 = new User(“張三”); User u2 = new User(“張三”); 由于我們重寫了User的equals方法,所以 u1.equals(u2);返回true 但是,User并沒有重寫hashCode方法,它用的是Object類的hashCode方法,所以 u1.hashCode = 31050006 u2.hashCode = 31587890 兩者的hashCode并不相等。違背了hibernate的原則 由此hibernate會產生錯誤判斷,又以為它們不是同一個對象,因此我們還得重寫User 的hashCode方法。如何重寫hashCode方法呢?

HashCode的重寫

如第2節(jié)所講,哈希碼要完成這么一件事,首先要保證如果equlas出來的結果相等,那么hashCode也相等。像上面的u1和u2,由于名字都是“張三”,所以應該返回相同的hashCode。所以我們可以想一個辦法。讓User的哈希碼返回User里面name字段的哈希碼,這樣就保證,名字相同的人,不但equlas方法相同,而且hashCode相等。 那么User類就變成 public class User{ private String userName; //覆蓋Object里的equals方法 public boolean equals(Object arg0){ if(!(arg0 instanceof User)){ return false; } User user = (User)arg0; //如果名字相同,則表示屬于同一個對象。 if (user.getName().equals(this.getName)){ return true; }else{ return false; } } //覆蓋Object里的hashCode方法 public int hashCode() { return name.hashCode();//返回名字的哈希碼。 } } 這樣可以保證hibernate根據(jù)我們自己的需求來判斷重復對象

Object類中 有幾個方法

Object類中的方法介紹 ????類Object是類層次結構的根類,每一個類都使用Object作為超類,所有對象(包括數(shù)組)都實現(xiàn)這個類的方法。jdk1.5中,描述了該類中的11個方法

1.getClass

public final Class<? extends Object> getClass()
返回一個對象的運行時類。該 Class 對象是由所表示類的 static synchronized 方法鎖定的對象。

?

返回:
表示該對象的運行時類的 java.lang.Class 對象。此結果屬于類型 Class<? extends X>,其中 X 表示清除表達式中的靜態(tài)類型,該表達式調用 getClass。

2.hashCode

public int hashCode()
返回該對象的哈希碼值。支持該方法是為哈希表提供一些優(yōu)點,例如,java.util.Hashtable 提供的哈希表。

hashCode 的常規(guī)協(xié)定是:

  • 在 Java 應用程序執(zhí)行期間,在同一對象上多次調用 hashCode 方法時,必須一致地返回相同的整數(shù),前提是對象上 equals 比較中所用的信息沒有被修改。從某一應用程序的一次執(zhí)行到同一應用程序的另一次執(zhí)行,該整數(shù)無需保持一致。
  • 如果根據(jù) equals(Object) 方法,兩個對象是相等的,那么在兩個對象中的每個對象上調用 hashCode 方法都必須生成相同的整數(shù)結果。
  • 以下情況不 是必需的:如果根據(jù) equals(java.lang.Object) 方法,兩個對象不相等,那么在兩個對象中的任一對象上調用 hashCode 方法必定會生成不同的整數(shù)結果。但是,程序員應該知道,為不相等的對象生成不同整數(shù)結果可以提高哈希表的性能。

實際上,由 Object 類定義的 hashCode 方法確實會針對不同的對象返回不同的整數(shù)。(這一般是通過將該對象的內部地址轉換成一個整數(shù)來實現(xiàn)的,但是 JavaTM 編程語言不需要這種實現(xiàn)技巧。)

?

返回:
此對象的一個哈希碼值。

3.equals

public boolean equals(Object?obj)
指示某個其他對象是否與此對象“相等”。

equals 方法在非空對象引用上實現(xiàn)相等關系:

  • 自反性:對于任何非空引用值 x,x.equals(x) 都應返回 true。
  • 對稱性:對于任何非空引用值 x 和 y,當且僅當 y.equals(x) 返回 true 時,x.equals(y) 才應返回 true。
  • 傳遞性:對于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 應返回 true。
  • 一致性:對于任何非空引用值 x 和 y,多次調用 x.equals(y) 始終返回 true 或始終返回 false,前提是對象上 equals 比較中所用的信息沒有被修改。
  • 對于任何非空引用值 x,x.equals(null) 都應返回 false。

Object 類的 equals 方法實現(xiàn)對象上差別可能性最大的相等關系;即,對于任何非空引用值 x 和 y,當且僅當 x 和 y 引用同一個對象時,此方法才返回 true(x == y 具有值 true)。

注意:當此方法被重寫時,通常有必要重寫 hashCode 方法,以維護 hashCode 方法的常規(guī)協(xié)定,該協(xié)定聲明相等對象必須具有相等的哈希碼。

?

參數(shù):
obj - 要與之比較的引用對象。
返回:
如果此對象與 obj 參數(shù)相同,則返回 true;否則返回 false。

4.clone

protected Object clone() throws CloneNotSupportedException
創(chuàng)建并返回此對象的一個副本。“副本”的準確含義可能依賴于對象的類。一般來說,對于任何對象 x,如果表達式: x.clone() != x 是正確的,則表達式: x.clone().getClass() == x.getClass() 將為 true,但這些不是絕對條件。一般情況下是: x.clone().equals(x) 將為 true,但這不是絕對條件。

按照慣例,返回的對象應該通過調用 super.clone 獲得。如果一個類及其所有的超類(Object 除外)都遵守此約定,則 x.clone().getClass() == x.getClass()。

按照慣例,此方法返回的對象應該獨立于該對象(正被克隆的對象)。要獲得此獨立性,在 super.clone 返回對象之前,有必要對該對象的一個或多個字段進行修改。這通常意味著要復制包含正在被克隆對象的內部“深層結構”的所有可變對象,并使用對副本的引用替換對這些對象的引用。如果一個類只包含基本字段或對不變對象的引用,那么通常不需要修改 super.clone 返回的對象中的字段。

Object 類的 clone 方法執(zhí)行特定的克隆操作。首先,如果此對象的類不能實現(xiàn)接口 Cloneable,則會拋出 CloneNotSupportedException。注意:所有的數(shù)組都被視為實現(xiàn)接口 Cloneable。否則,此方法會創(chuàng)建此對象的類的一個新實例,并像通過分配那樣,嚴格使用此對象相應字段的內容初始化該對象的所有字段;這些字段的內容沒有被自我克隆。所以,此方法執(zhí)行的是該對象的“淺表復制”,而不“深層復制”操作。

Object 類本身不實現(xiàn)接口 Cloneable,所以在類為 Object 的對象上調用 clone 方法將會導致在運行時拋出異常。

?

返回:
此實例的一個克隆。
拋出:
CloneNotSupportedException - 如果對象的類不支持 Cloneable 接口,則重寫 clone 方法的子類也會拋出此異常,以指示無法克隆某個實例。

5.toString

public String toString()
返回該對象的字符串表示。通常,toString 方法會返回一個“以文本方式表示”此對象的字符串。結果應是一個簡明但易于讀懂。建議所有子類都重寫此方法。

Object 類的 toString 方法返回一個字符串,該字符串由類名(對象是該類的一個實例)、at 標記符“@”和此對象哈希碼的無符號十六進制表示組成。換句話說,該方法返回一個字符串,它的值等于:

getClass().getName() + '@' + Integer.toHexString(hashCode())

?

返回:
該對象的字符串表示形式。

6.notify

public final void notify()
喚醒在此對象監(jiān)視器上等待的單個線程。如果所有線程都在此對象上等待,則會選擇喚醒其中一個線程。選擇是任意性的,并在對實現(xiàn)做出決定時發(fā)生。線程通過調用其中一個 wait 方法,在對象的監(jiān)視器上等待。

直到當前的線程放棄此對象上的鎖定,才能繼續(xù)執(zhí)行被喚醒的線程。被喚醒的線程將以常規(guī)方式與在該對象上主動同步的其他所有線程進行競爭;例如,喚醒的線程在作為鎖定此對象的下一個線程方面沒有可靠的特權或劣勢。

此方法只應由作為此對象監(jiān)視器的所有者的線程來調用。通過以下三種方法之一,線程可以成為此對象監(jiān)視器的所有者:

  • 通過執(zhí)行此對象的同步 (Sychronized) 實例方法。
  • 通過執(zhí)行在此對象上進行同步的 synchronized 語句的正文。
  • 對于 Class 類型的對象,可以通過執(zhí)行該類的同步靜態(tài)方法。

一次只能有一個線程擁有對象的監(jiān)視器。

?

拋出:
IllegalMonitorStateException - 如果當前的線程不是此對象監(jiān)視器的所有者。

7.notifyAll

public final void notifyAll()
喚醒在此對象監(jiān)視器上等待的所有線程。線程通過調用其中一個 wait 方法,在對象的監(jiān)視器上等待。

直到當前的線程放棄此對象上的鎖定,才能繼續(xù)執(zhí)行被喚醒的線程。被喚醒的線程將以常規(guī)方式與在該對象上主動同步的其他所有線程進行競爭;例如,喚醒的線程在作為鎖定此對象的下一個線程方面沒有可靠的特權或劣勢。

此方法只應由作為此對象監(jiān)視器的所有者的線程來調用。請參閱 notify 方法,了解線程能夠成為監(jiān)視器所有者的方法的描述。

?

拋出:
IllegalMonitorStateException - 如果當前的線程不是此對象監(jiān)視器的所有者。

8.finalize

protected void finalize() throws Throwable
當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。子類重寫 finalize 方法,以配置系統(tǒng)資源或執(zhí)行其他清除。

finalize 的常規(guī)協(xié)定是:當 JavaTM 虛擬機已確定尚未終止的任何線程無法再通過任何方法訪問此對象時,將調用此方法,除非由于準備終止的其他某個對象或類的終結操作執(zhí)行了某個操作。finalize 方法可以采取任何操作,其中包括再次使此對象對其他線程可用;不過,finalize 的主要目的是在不可撤消地丟棄對象之前執(zhí)行清除操作。例如,表示輸入/輸出連接的對象的 finalize 方法可執(zhí)行顯式 I/O 事務,以便在永久丟棄對象之前中斷連接。

Object 類的 finalize 方法執(zhí)行非特殊性操作;它僅執(zhí)行一些常規(guī)返回。Object 的子類可以重寫此定義。

Java 編程語言不保證哪個線程將調用某個給定對象的 finalize 方法。但可以保證在調用 finalize 時,調用 finalize 的線程將不會持有任何用戶可見的同步鎖定。如果 finalize 方法拋出未捕獲的異常,那么該異常將被忽略,并且該對象的終結操作將終止。

在啟用某個對象的 finalize 方法后,將不會執(zhí)行進一步操作,直到 Java 虛擬機再次確定尚未終止的任何線程無法再通過任何方法訪問此對象,其中包括由準備終止的其他對象或類執(zhí)行的可能操作,在執(zhí)行該操作時,對象可能被丟棄。

對于任何給定對象,Java 虛擬機最多只調用一次 finalize 方法。

finalize 方法拋出的任何異常都會導致此對象的終結操作停止,但可以通過其他方法忽略它。

?

拋出:
Throwable - 此方法拋出的 Exception

9.wait

public final void wait(long?timeout) throws InterruptedException
導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量。

當前的線程必須擁有此對象監(jiān)視器。

此方法導致當前線程(稱之為 T)將其自身放置在對象的等待集中,然后放棄此對象上的所有同步要求。出于線程調度目的,線程 T 被禁用,且處于休眠狀態(tài),直到發(fā)生以下四種情況之一:

  • 其他某個線程調用此對象的 notify 方法,并且線程 T 碰巧被任選為被喚醒的線程。
  • 其他某個線程調用此對象的 notifyAll 方法。
  • 其他某個線程中斷線程 T。
  • 已經(jīng)到達指定的實際時間。但是,如果 timeout 為零,則不考慮實際時間,該線程將一直等待,直到獲得通知。
然后,從對象的等待集中刪除線程 T,并重新進行線程調度。然后,該線程以常規(guī)方式與其他線程競爭,以獲得在該對象上同步的權利;一旦獲得對該對象的控制權,該對象上的所有其同步聲明都將被還原到以前的狀態(tài) - 這就是調用 wait 方法時的情況。然后,線程 T 從 wait 方法的調用中返回。所以,從 wait 方法返回時,該對象和線程 T 的同步狀態(tài)與調用 wait 方法時的情況完全相同。

在沒有被通知、中斷或超時的情況下,線程還可以喚醒一個所謂的虛假喚醒 (spurious wakeup)。雖然這種情況在實踐中很少發(fā)生,但是應用程序必須通過以下方式防止其發(fā)生,即對應該導致該線程被提醒的條件進行測試,如果不滿足該條件,則繼續(xù)等待。換句話說,等待應總是發(fā)生在循環(huán)中,如下面的示例:

synchronized (obj) { while (<condition does not hold>) obj.wait(timeout); ... // Perform action appropriate to condition } (有關這一主題的更多信息,請參閱 Doug Lea 撰寫的《Concurrent Programming in Java (Second Edition)》(Addison-Wesley, 2000) 中的第 3.2.3 節(jié)或 Joshua Bloch 撰寫的《Effective Java Programming Language Guide》(Addison-Wesley, 2001) 中的第 50 項。

如果當前線程在等待時被其他線程中斷,則會拋出 InterruptedException。在按上述形式恢復此對象的鎖定狀態(tài)時才會拋出此異常。

注意,由于 wait 方法將當前的線程放入了對象的等待集中,所以它只能解除此對象的鎖定;可以同步當前線程的任何其他對象在線程等待時仍處于鎖定狀態(tài)。

此方法只應由作為此對象監(jiān)視器的所有者的線程來調用。請參閱 notify 方法,了解線程能夠成為監(jiān)視器所有者的方法的描述。

?

參數(shù):
timeout - 要等待的最長時間(以毫秒為單位)。
拋出:
IllegalArgumentException - 如果超時值為負。
IllegalMonitorStateException - 如果當前的線程不是此對象監(jiān)視器的所有者。
InterruptedException - 如果在當前線程等待通知之前或者正在等待通知時,另一個線程中斷了當前線程。在拋出此異常時,當前線程的中斷狀態(tài) 被清除。

10.wait

public final void wait(long?timeout, int?nanos) throws InterruptedException
導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量。

此方法類似于一個參數(shù)的 wait 方法,但它允許更好地控制在放棄之前等待通知的時間量。用毫微秒度量的實際時間量可以通過以下公式計算出來:

1000000*timeout+nanos

在其他所有方面,此方法執(zhí)行的操作與帶有一個參數(shù)的 wait(long) 方法相同。需要特別指出的是,wait(0, 0) 與 wait(0) 相同。

當前的線程必須擁有此對象監(jiān)視器。該線程發(fā)布對此監(jiān)視器的所有權,并等待下面兩個條件之一發(fā)生:

  • 其他線程通過調用 notify 方法,或 notifyAll 方法通知在此對象的監(jiān)視器上等待的線程醒來。
  • timeout 毫秒值與 nanos 毫微秒?yún)?shù)值之和指定的超時時間已用完。

然后,該線程等到重新獲得對監(jiān)視器的所有權后才能繼續(xù)執(zhí)行。

對于某一個參數(shù)的版本,實現(xiàn)中斷和虛假喚醒是有可能的,并且此方法應始終在循環(huán)中使用:

synchronized (obj) { while (<condition does not hold>) obj.wait(timeout, nanos); ... // Perform action appropriate to condition } 此方法只應由作為此對象監(jiān)視器的所有者的線程來調用。請參閱 notify 方法,了解線程能夠成為監(jiān)視器所有者的方法的描述。

?

參數(shù):
timeout - 要等待的最長時間(以毫秒為單位)。
nanos - 額外時間(以毫微秒為單位,范圍是 0-999999)。
拋出:
IllegalArgumentException - 如果超時值是負數(shù),或者毫微秒值不在 0-999999 范圍內。
IllegalMonitorStateException - 如果當前線程不是此對象監(jiān)視器的所有者。
InterruptedException - 如果在當前線程等待通知之前或者正在等待通知時,其他線程中斷了當前線程。在拋出此異常時,當前線程的中斷狀態(tài) 被清除。

11.wait

public final void wait() throws InterruptedException
導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法。換句話說,此方法的行為就好像它僅執(zhí)行 wait(0) 調用一樣。

當前的線程必須擁有此對象監(jiān)視器。該線程發(fā)布對此監(jiān)視器的所有權并等待,直到其他線程通過調用 notify 方法,或 notifyAll 方法通知在此對象的監(jiān)視器上等待的線程醒來。然后該線程將等到重新獲得對監(jiān)視器的所有權后才能繼續(xù)執(zhí)行。

對于某一個參數(shù)的版本,實現(xiàn)中斷和虛假喚醒是可能的,而且此方法應始終在循環(huán)中使用:

synchronized (obj) { while (<condition does not hold>) obj.wait(); ... // Perform action appropriate to condition } 此方法只應由作為此對象監(jiān)視器的所有者的線程來調用。請參閱 notify 方法,了解線程能夠成為監(jiān)視器所有者的方法的描述。

?

拋出:
IllegalMonitorStateException - 如果當前的線程不是此對象監(jiān)視器的所有者。
InterruptedException - 如果在當前線程等待通知之前或者正在等待通知時,另一個線程中斷了當前線程。在拋出此異常時,當前線程的中斷狀態(tài) 被清除。

總結

以上是生活随笔為你收集整理的java 哈希码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 好吊妞精品 | 色丁香婷婷 | 人妻精品久久久久中文字幕 | 国产成人在线免费观看 | 天天干天天做天天操 | 泷泽萝拉在线播放 | 亚洲人一区 | 黄色www| 蜜臀视频一区二区 | 欧美www视频 | 三级欧美日韩 | 先锋影音一区二区三区 | 欧美精品二区三区四区免费看视频 | 欧美三级在线播放 | 九九热最新视频 | 黑帮大佬和我的365日第二部 | 狼人伊人av | av专区在线 | 国产午夜精品一区二区理论影院 | 偷拍视频久久 | 欧美黄色性视频 | 激情av小说| 亚洲视频在线播放 | 性视频在线| 黄色大片aa | 天天射网 | 婷婷伊人五月 | 五月综合激情 | 亚洲尤物视频 | 瑟瑟在线观看 | 1级片在线观看 | 狠狠搞av | 亚洲欧洲视频在线观看 | av在线导航| 精品一二三区久久aaa片 | 中文字幕av网址 | 美女少妇av| 免费超爽大片黄 | 丰满少妇乱子伦精品看片 | 久久久久久国产 | 婷婷六月综合 | 二级毛片| 精品国产午夜福利在线观看 | 日本熟妇人妻中出 | 噜噜av| 色就是色综合 | www.我爱av| 男男成人高潮片免费网站 | 永久免费看mv网站入口78 | 外国黄色网 | 亚洲一区二区成人 | 日韩欧美国产高清91 | 加勒比精品| 欧美日韩国产亚洲一区 | 韩国成人免费视频 | 好吊色视频一区二区三区 | 人妻互换一二三区激情视频 | 精品三级在线 | 性欧美lx╳lx╳ | 成人av男人的天堂 | 三度诱惑免费版电影在线观看 | 亚洲视频精品一区 | 奇米成人影视 | 欧美成人精品欧美一级私黄 | 日本天堂在线观看 | 国产精品麻豆一区二区三区 | 日韩大片免费 | 中文字幕在线视频免费观看 | 91毛片观看| 娇小6一8小毛片 | 女人洗澡一级特黄毛片 | 日本乱淫视频 | 欧美特黄一区二区三区 | 天堂国产一区二区三区 | 91影视在线观看 | 久久久久人妻精品一区二区三区 | 欧美一区二区免费电影 | 337p粉嫩大胆噜噜噜亚瑟影院 | 男女无遮挡免费视频 | 不用播放器看av | 91国内 | 人妻一区二区三区四区五区 | 五月天中文字幕在线 | 日韩av在线看免费观看 | 精品久久久久久久久久久 | 99色视频 | 91大神在线看 | 麻豆md0049免费 | 色图插插插 | 中文字幕在线视频观看 | 一区二区三区免费在线视频 | 青青草在线观看视频 | 亚洲精品一区二区三区四区五区 | 日本三级中文字幕 | 色一情一乱一伦一区二区三区 | 激情影院内射美女 | 顶级毛片| 国产片一区二区三区 | 欧美男女激情 |