国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
Java 中 hashCode() 方法的意義是什么?
Java 中 hashCode() 方法是如何工作的?
Java 中 equals()hashCode() 方法之間的約定是什么?
如何在 Java 中重寫 hashCode() 方法?
什么是哈希沖突,如何避免?
為什么應(yīng)該重寫 hashCode() 方法?
在 Java 中,兩個(gè)不相等的對(duì)象可以具有相同的 hashCode 嗎?
如果我不重寫 hashCode() 方法會(huì)發(fā)生什么?
我可以在非基于哈希的集合中使用 hashCode() 方法嗎?
首頁 科技周邊 IT業(yè)界 如何正確實(shí)現(xiàn)java s HashCode

如何正確實(shí)現(xiàn)java s HashCode

Feb 18, 2025 am 10:46 AM

SitePoint 探索 Java 世界:誠邀 Java 開發(fā)者投稿

How to Implement Java's hashCode Correctly

SitePoint 持續(xù)拓展內(nèi)容領(lǐng)域,近期將重點(diǎn)關(guān)注 Java。如果您是經(jīng)驗(yàn)豐富的 Java 開發(fā)者,并希望為我們的 Java 內(nèi)容貢獻(xiàn)力量,歡迎聯(lián)系我們,分享您想撰寫的文章主題構(gòu)想。

Java 中 equalshashCode 方法的正確實(shí)現(xiàn)

您已為您的類實(shí)現(xiàn)了 equals 方法?很棒!但您也必須實(shí)現(xiàn) hashCode 方法。讓我們了解原因以及如何正確實(shí)現(xiàn)它。

關(guān)鍵要點(diǎn):

  • 在 Java 中,相等的對(duì)象應(yīng)具有相同的哈希碼。因此,如果重寫了 equals 方法,則必須創(chuàng)建匹配的 hashCode 實(shí)現(xiàn),以確保在基于哈希的集合中存儲(chǔ)和檢索對(duì)象的準(zhǔn)確性和一致性。
  • 實(shí)現(xiàn) hashCode 時(shí),應(yīng)使用與 equals 方法中使用的相同字段。應(yīng)盡量避免使用可變字段和集合,因?yàn)檫@可能會(huì)導(dǎo)致性能問題。
  • 哈希碼與性能優(yōu)化相關(guān),因此除非性能分析表明需要改進(jìn),否則不應(yīng)在哈希上投入過多精力。
  • 哈希沖突(兩個(gè)不同的對(duì)象具有相同的哈希碼)可以通過改進(jìn)哈希算法和使用更大的質(zhì)數(shù)作為乘數(shù)來減少。這有助于更均勻地將哈希碼分布在集合中,從而減少哈希沖突的可能性并確保更快的數(shù)據(jù)檢索。

equalshashCode 方法

雖然 equals 方法從一般角度來看是合理的,但 hashCode 方法則更具技術(shù)性。嚴(yán)格來說,它只是一個(gè)用于提高性能的實(shí)現(xiàn)細(xì)節(jié)。

大多數(shù)數(shù)據(jù)結(jié)構(gòu)使用 equals 方法來檢查它們是否包含某個(gè)元素。例如:

List<String> list = Arrays.asList("a", "b", "c");
boolean contains = list.contains("b");

變量 contains 為真,因?yàn)殡m然 "b" 的實(shí)例并不相同(再次忽略字符串駐留),但它們是相等的。

然而,將每個(gè)元素與傳遞給 contains 方法的實(shí)例進(jìn)行比較效率低下,而一類數(shù)據(jù)結(jié)構(gòu)則使用更高效的方法。它們不將請(qǐng)求的實(shí)例與它們包含的每個(gè)元素進(jìn)行比較,而是使用快捷方式來減少可能相等的實(shí)例數(shù)量,然后只比較這些實(shí)例。

這個(gè)快捷方式就是哈希碼,它可以被視為對(duì)象的相等性簡(jiǎn)化為一個(gè)整數(shù)值。具有相同哈希碼的實(shí)例不一定是相等的,但相等的實(shí)例具有相同的哈希碼。(或者應(yīng)該具有相同的哈希碼,我們稍后將討論這一點(diǎn)。)此類數(shù)據(jù)結(jié)構(gòu)通常以其技術(shù)名稱命名,其名稱中包含 "Hash",其中 HashMap 是最著名的代表。

它們通常的工作方式如下:

  • 添加元素時(shí),使用其哈希碼計(jì)算內(nèi)部數(shù)組(稱為桶)中的索引。
  • 如果其他不相等的元素具有相同的哈希碼,則它們最終會(huì)進(jìn)入同一個(gè)桶中,并且必須捆綁在一起,例如通過將它們添加到列表中。
  • 將實(shí)例傳遞給 contains 方法時(shí),使用其哈希碼計(jì)算桶。只有其中的元素才會(huì)與該實(shí)例進(jìn)行比較。

這樣,實(shí)現(xiàn) contains 方法可能只需要很少的,理想情況下不需要任何 equals 比較。

equals 方法一樣,hashCode 方法也在 Object 類中定義。

關(guān)于哈希的思考

如果 hashCode 方法用作確定相等性的快捷方式,那么我們真正應(yīng)該關(guān)心的只有一件事:相等的對(duì)象應(yīng)該具有相同的哈希碼。

這也是為什么如果我們重寫 equals 方法,就必須創(chuàng)建一個(gè)匹配的 hashCode 實(shí)現(xiàn)的原因!否則,根據(jù)我們的實(shí)現(xiàn)相等的事物可能不會(huì)具有相同的哈希碼,因?yàn)樗鼈兪褂?Object 類的實(shí)現(xiàn)。

hashCode 方法的約定

引用源代碼:

hashCode 方法的一般約定是:

  • 每當(dāng)在 Java 應(yīng)用程序的執(zhí)行過程中多次對(duì)同一個(gè)對(duì)象調(diào)用它時(shí),hashCode 方法必須始終返回相同的整數(shù),前提是沒有修改在對(duì)象的 equals 比較中使用的信息。此整數(shù)不必在一個(gè)應(yīng)用程序的執(zhí)行與同一應(yīng)用程序的另一個(gè)執(zhí)行之間保持一致。
  • 如果根據(jù) equals(Object) 方法,兩個(gè)對(duì)象相等,則對(duì)這兩個(gè)對(duì)象中的每一個(gè)調(diào)用 hashCode 方法必須產(chǎn)生相同的整數(shù)結(jié)果。
  • 如果根據(jù) equals(Object) 方法,兩個(gè)對(duì)象不相等,則不需要調(diào)用這兩個(gè)對(duì)象上的 hashCode 方法必須產(chǎn)生不同的整數(shù)結(jié)果。但是,程序員應(yīng)該意識(shí)到,為不相等的對(duì)象生成不同的整數(shù)結(jié)果可以提高哈希表的性能。

第一點(diǎn)反映了 equals 方法的一致性屬性,第二點(diǎn)是我們上面得出的要求。第三點(diǎn)說明了一個(gè)重要的細(xì)節(jié),我們稍后將討論。

實(shí)現(xiàn) hashCode 方法

一個(gè)非常簡(jiǎn)單的 Person.hashCode 實(shí)現(xiàn)如下:

List<String> list = Arrays.asList("a", "b", "c");
boolean contains = list.contains("b");

人的哈希碼是通過計(jì)算相關(guān)字段的哈希碼并將它們組合起來計(jì)算的。兩者都留給 Objects 的實(shí)用程序函數(shù) hash 來處理。

選擇字段

但是哪些字段是相關(guān)的呢?這些要求有助于回答這個(gè)問題:如果相等的對(duì)象必須具有相同的哈希碼,那么哈希碼計(jì)算不應(yīng)包含任何未用于相等性檢查的字段。(否則,只有在這些字段上不同的兩個(gè)對(duì)象將是相等的,但具有不同的哈希碼。)

因此,用于哈希的字段集應(yīng)該是用于相等性的字段集的子集。默認(rèn)情況下,兩者都將使用相同的字段,但有一些細(xì)節(jié)需要考慮。

一致性

首先,有一致性要求。它應(yīng)該被相當(dāng)嚴(yán)格地解釋。雖然它允許在某些字段發(fā)生更改時(shí)哈希碼發(fā)生更改(對(duì)于可變類來說這通常是不可避免的),但哈希數(shù)據(jù)結(jié)構(gòu)并未為此場(chǎng)景做好準(zhǔn)備。

正如我們上面所看到的,哈希碼用于確定元素的桶。但是,如果哈希相關(guān)字段發(fā)生更改,則不會(huì)重新計(jì)算哈希,并且不會(huì)更新內(nèi)部數(shù)組。

這意味著使用相等的對(duì)象或甚至使用完全相同的實(shí)例的后續(xù)查詢將失??!數(shù)據(jù)結(jié)構(gòu)計(jì)算當(dāng)前的哈希碼(與用于存儲(chǔ)實(shí)例的哈希碼不同),并在錯(cuò)誤的桶中查找。

結(jié)論:最好不要使用可變字段進(jìn)行哈希碼計(jì)算!

性能

哈希碼的計(jì)算次數(shù)可能與 equals 方法的調(diào)用次數(shù)大致相同。這很可能發(fā)生在代碼的關(guān)鍵性能部分,因此考慮性能是有意義的。并且與 equals 方法不同,這里有更多空間進(jìn)行優(yōu)化。

除非使用復(fù)雜的算法或涉及許多字段,否則組合其哈希碼的算術(shù)成本與不可避免的成本一樣微不足道。但是應(yīng)該考慮是否需要將所有字段都包含在計(jì)算中!特別是應(yīng)該對(duì)集合持懷疑態(tài)度。例如,列表和集合將為它們的每個(gè)元素計(jì)算哈希值。是否需要調(diào)用它們應(yīng)該根據(jù)具體情況進(jìn)行考慮。

如果性能至關(guān)重要,使用 Objects.hash 也可能不是最佳選擇,因?yàn)樗枰獮槠淇勺儏?shù)創(chuàng)建數(shù)組。

但是關(guān)于優(yōu)化的通用規(guī)則仍然適用:不要過早優(yōu)化!使用常見的哈希碼算法,也許放棄包含集合,并且只有在性能分析顯示存在改進(jìn)的可能性后才進(jìn)行優(yōu)化。

沖突

全力以赴追求性能,那么這個(gè)實(shí)現(xiàn)怎么樣?

List<String> list = Arrays.asList("a", "b", "c");
boolean contains = list.contains("b");

它肯定很快。并且相等的對(duì)象將具有相同的哈希碼,所以我們?cè)谶@方面也很好。作為獎(jiǎng)勵(lì),沒有涉及可變字段!

但是請(qǐng)記住我們之前關(guān)于桶的內(nèi)容?這樣所有實(shí)例都將進(jìn)入同一個(gè)桶!這通常會(huì)導(dǎo)致一個(gè)鏈表保存所有元素,這對(duì)性能來說非常糟糕。例如,每個(gè) contains 調(diào)用都會(huì)觸發(fā)鏈表的線性掃描。

因此,我們希望盡可能減少同一個(gè)桶中的項(xiàng)目數(shù)量!即使對(duì)于非常相似的對(duì)象,也能返回差異很大的哈希碼的算法是一個(gè)良好的開端。如何實(shí)現(xiàn)部分取決于所選字段。我們?cè)谟?jì)算中包含的細(xì)節(jié)越多,哈希碼不同的可能性就越大。請(qǐng)注意,這與我們對(duì)性能的想法完全相反。因此,有趣的是,使用過多過少的字段都可能導(dǎo)致性能不佳。

防止沖突的另一部分是用于實(shí)際計(jì)算哈希的算法。

計(jì)算哈希值

計(jì)算字段哈希碼的最簡(jiǎn)單方法是對(duì)其調(diào)用 hashCode 方法??梢允謩?dòng)組合它們。一個(gè)常見的算法是從某個(gè)任意數(shù)字開始,然后重復(fù)地將其與另一個(gè)數(shù)字(通常是一個(gè)小的質(zhì)數(shù))相乘,然后再添加字段的哈希值:

List<String> list = Arrays.asList("a", "b", "c");
boolean contains = list.contains("b");

這可能會(huì)導(dǎo)致溢出,但這在 Java 中不會(huì)導(dǎo)致異常,因此問題不大。

請(qǐng)注意,即使是優(yōu)秀的哈希算法,如果輸入數(shù)據(jù)具有特定模式,也可能導(dǎo)致異常頻繁的沖突。作為一個(gè)簡(jiǎn)單的例子,假設(shè)我們通過添加點(diǎn)的 x 和 y 坐標(biāo)來計(jì)算點(diǎn)的哈希值。這聽起來還不錯(cuò),直到我們意識(shí)到我們經(jīng)常處理直線 f(x) = -x 上的點(diǎn),這意味著對(duì)于所有這些點(diǎn),x y == 0。沖突,很多!

但是再次強(qiáng)調(diào):使用常見的算法,并且除非性能分析顯示存在問題,否則不要擔(dān)心。

總結(jié)

我們已經(jīng)看到,計(jì)算哈希碼就像將相等性壓縮為整數(shù)值:相等的對(duì)象必須具有相同的哈希碼,并且出于性能原因,最好盡可能少的不相等對(duì)象共享相同的哈希碼。

這意味著如果重寫了 equals 方法,則必須始終重寫 hashCode 方法。

實(shí)現(xiàn) hashCode 方法時(shí):

  • 使用與 equals 方法中使用的相同字段(或其子集)。
  • 最好不要包含可變字段。
  • 考慮不調(diào)用集合上的 hashCode 方法。
  • 使用常見的算法,除非輸入數(shù)據(jù)的模式與之相反。

記住,hashCode 方法與性能有關(guān),因此除非性能分析表明有必要,否則不要浪費(fèi)太多精力。

關(guān)于正確實(shí)現(xiàn) Java hashCode 方法的常見問題解答 (FAQ)

Java 中 hashCode() 方法的意義是什么?

Java 中的 hashCode() 方法是一個(gè)內(nèi)置函數(shù),它返回一個(gè)整數(shù)值。它主要用于基于哈希的集合(如 HashMap、HashSetHashTable)以更有效地存儲(chǔ)和檢索對(duì)象。hashCode() 方法與 equals() 方法協(xié)同工作,以確保每個(gè)對(duì)象都有一個(gè)唯一的標(biāo)識(shí)符。這有助于快速檢索數(shù)據(jù),尤其是在大型集合中,從而提高 Java 應(yīng)用程序的性能。

Java 中 hashCode() 方法是如何工作的?

Java 中的 hashCode() 方法的工作原理是生成一個(gè)整數(shù)值,該值表示對(duì)象的內(nèi)存地址。此值用作對(duì)象在基于哈希的集合中的索引號(hào)。當(dāng)您對(duì)對(duì)象調(diào)用 hashCode() 方法時(shí),它會(huì)使用哈希算法來生成此唯一整數(shù)。但是,需要注意的是,兩個(gè)不同的對(duì)象可能具有相同的 hashCode,這被稱為哈希沖突。

Java 中 equals()hashCode() 方法之間的約定是什么?

Java 中 equals()hashCode() 方法之間的約定是一組規(guī)則,用于管理它們的交互。該約定指出,如果根據(jù) equals() 方法,兩個(gè)對(duì)象相等,則對(duì)這兩個(gè)對(duì)象中的每一個(gè)調(diào)用 hashCode() 方法必須產(chǎn)生相同的整數(shù)結(jié)果。這確保了在基于哈希的集合中存儲(chǔ)和檢索對(duì)象時(shí)的一致性和準(zhǔn)確性。

如何在 Java 中重寫 hashCode() 方法?

在 Java 中重寫 hashCode() 方法包括提供您自己的實(shí)現(xiàn),該實(shí)現(xiàn)為每個(gè)對(duì)象返回一個(gè)唯一的整數(shù)。這可以通過使用對(duì)象的實(shí)例變量和質(zhì)數(shù)乘數(shù)來實(shí)現(xiàn)。質(zhì)數(shù)有助于將哈希碼均勻地分布在集合中,從而減少哈希沖突的可能性。

什么是哈希沖突,如何避免?

哈希沖突是指 hashCode() 方法為兩個(gè)不同的對(duì)象生成相同的整數(shù)。如果處理不當(dāng),這可能會(huì)導(dǎo)致數(shù)據(jù)丟失。為了避免哈希沖突,您可以改進(jìn)哈希算法以生成更多唯一的整數(shù)。此外,使用更大的質(zhì)數(shù)作為乘數(shù)可以幫助更均勻地將哈希碼分布在集合中。

為什么應(yīng)該重寫 hashCode() 方法?

重寫 hashCode() 方法可以提高 Java 應(yīng)用程序的性能,尤其是在處理大型集合時(shí)。通過提供您自己的實(shí)現(xiàn),您可以生成更唯一且更均勻分布的哈希碼,從而減少哈希沖突的可能性并確保更快的數(shù)據(jù)檢索。

在 Java 中,兩個(gè)不相等的對(duì)象可以具有相同的 hashCode 嗎?

是的,在 Java 中,兩個(gè)不相等的對(duì)象可以具有相同的 hashCode。這被稱為哈希沖突。但是,通過改進(jìn)哈希算法和使用更大的質(zhì)數(shù)作為乘數(shù),可以降低這種情況發(fā)生的可能性。

如果我不重寫 hashCode() 方法會(huì)發(fā)生什么?

如果您不重寫 hashCode() 方法,Java 將使用其默認(rèn)實(shí)現(xiàn),這可能無法為每個(gè)對(duì)象提供唯一的哈希碼。這可能導(dǎo)致哈希沖突和基于哈希的集合中更慢的數(shù)據(jù)檢索。

hashCode() 方法如何提高 Java 應(yīng)用程序的性能?

hashCode() 方法通過為每個(gè)對(duì)象提供唯一的標(biāo)識(shí)符來提高 Java 應(yīng)用程序的性能。這允許在基于哈希的集合中更快地檢索數(shù)據(jù),因?yàn)榭梢允褂脤?duì)象的哈希碼直接找到該對(duì)象,而無需搜索整個(gè)集合。

我可以在非基于哈希的集合中使用 hashCode() 方法嗎?

雖然 hashCode() 方法主要用于基于哈希的集合,但它也可以用于非基于哈希的集合。但是,其好處可能不那么明顯,因?yàn)榉腔诠5募喜灰蕾囉诠4a進(jìn)行數(shù)據(jù)存儲(chǔ)和檢索。

以上是如何正確實(shí)現(xiàn)java s HashCode的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
您的設(shè)備喂養(yǎng)AI助手并收集個(gè)人數(shù)據(jù),即使他們睡著了。這是如何知道您分享的內(nèi)容。 您的設(shè)備喂養(yǎng)AI助手并收集個(gè)人數(shù)據(jù),即使他們睡著了。這是如何知道您分享的內(nèi)容。 Jul 05, 2025 am 01:12 AM

不管喜歡與否,人工智能已成為日常生活的一部分。許多設(shè)備(包括電動(dòng)剃須刀和牙刷)已成為AI驅(qū)動(dòng)的“使用機(jī)器學(xué)習(xí)算法來跟蹤一個(gè)人的使用方式,Devi的方式

由于新的Microsoft AI型號(hào) 由于新的Microsoft AI型號(hào) Jul 05, 2025 am 12:44 AM

一種新的人工智能(AI)模型已經(jīng)證明了比幾個(gè)使用最廣泛使用的全球預(yù)測(cè)系統(tǒng)更快,更精確地預(yù)測(cè)重大天氣事件的能力。該名為Aurora的模型已接受過培訓(xùn)。

高級(jí)AI型號(hào)的CO&#8322;回答相同問題時(shí)的排放量比更常見的LLM 高級(jí)AI型號(hào)的CO&#8322;回答相同問題時(shí)的排放量比更常見的LLM Jul 06, 2025 am 12:37 AM

根據(jù)最近的一項(xiàng)研究,我們?cè)噲D使AI模型的功能越精確,其碳排放量就越大 - 某些提示產(chǎn)生的二氧化碳比其他提示高達(dá)50倍。

ai不斷地'幻覺”,但是有一個(gè)解決方案 ai不斷地'幻覺”,但是有一個(gè)解決方案 Jul 07, 2025 am 01:26 AM

大型技術(shù)實(shí)驗(yàn)人工智能(AI)的主要關(guān)注點(diǎn)并不是它可能主導(dǎo)人類。真正的問題在于大語言模型(LLMS)的持續(xù)不準(zhǔn)確性,例如Open AI的Chatgpt,Google的Gemini和

研究表明,當(dāng)問題變得太困難時(shí) 研究表明,當(dāng)問題變得太困難時(shí) Jul 07, 2025 am 01:02 AM

人工智能(AI)推理模型并不像看起來那樣能力。實(shí)際上,根據(jù)Apple的研究人員的說法,當(dāng)任務(wù)變得過于復(fù)雜時(shí),它們的表現(xiàn)會(huì)完全崩潰。

在網(wǎng)絡(luò)攻擊M&S和合作社的網(wǎng)絡(luò)攻擊背后捕獲了狩獵者的逮捕 在網(wǎng)絡(luò)攻擊M&S和合作社的網(wǎng)絡(luò)攻擊背后捕獲了狩獵者的逮捕 Jul 11, 2025 pm 01:36 PM

英國國家犯罪局(NCA)逮捕了四名涉嫌參與針對(duì)Marks和Spencer(M&S),合作社和Harrods的網(wǎng)絡(luò)攻擊的人

Quantum Pryptography現(xiàn)在是網(wǎng)絡(luò)安全領(lǐng)導(dǎo)者的首要思想 Quantum Pryptography現(xiàn)在是網(wǎng)絡(luò)安全領(lǐng)導(dǎo)者的首要思想 Jul 11, 2025 pm 01:38 PM

Quantum加密術(shù)已成為網(wǎng)絡(luò)安全領(lǐng)導(dǎo)者的重中之重,但最近的研究表明,某些組織并沒有以其要求對(duì)待威脅。QuantumComputers最終能夠解決T

See all articles