亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

關于hashCode()你需要了解的3件事

2019-11-14 15:24:16
字體:
來源:轉載
供稿:網友

(點擊上方公眾號,可快速關注)

 

原文:eclipsesource

譯文:ImportNew - 南半球

鏈接:http://www.importnew.com/16517.html

 

java 中,每一個對象都有一個容易理解但是仍然有時候被遺忘或者被誤用的 hashCode 方法。這里有3件事情要時刻牢記以避免常見的陷阱。

 

一個對象的哈希碼允許算法和數據結構將對象放入隔間,就象打印機類型案件中的字母類型。打印機將所有的“A”類型放到一個房間,它尋找這個“A”的時候就只需要在這個房間進行尋找。這種簡單的系統讓他在未排序的抽屜中尋找類型的時候更快。這也是基于哈希的集合的想法,例如 HashMap 和 HashSet。

 

 

為了使你的類與其他基于哈希的集合或其他依賴哈希碼的算法一起正常工作,所有 hashCode 的實現必須遵守一個簡單的契約。

 

hashCode 契約

 

這個契約在 hashCode 方法的 JavaDoc 中進行了闡述。它可以大致的歸納為下面幾點:

 

  1. 在一個運行的進程中,相等的對象必須要有相同的哈希碼

  2. 請注意這并不意味著以下常見的誤解:

  3. 不相等的對象一定有著不同的哈希碼——錯!

  4. 有同一個哈希值的對象一定相等——錯!

 

 

這個契約允許不同的對象共享相同的哈希碼,例如根據上圖中的的描述,“A”和“μ”對象的哈希值就一樣。在數學術語中,從對象到哈希碼的映射不一定為內射或者雙射。這是顯而易見的,因為可能的不同對象的數量經常比可能的哈希嗎的數量 (2^32)更大。

 

編輯:在早期的版本中,我錯誤的認為哈希碼的映射一定屬于內射,但是不一定是雙射,這顯然是錯的。感謝 Lucian 指出這個錯誤。

 

這個約定直接導致了第一個規則:

 

1. 無論你何時實現 equals 方法,你必須同時實現 hashCode 方法

 

如果你不這樣做,你將會帶來損壞的對象。為什么?一個對象的 hashCode 方法需要與 equals 方法考慮同樣的域。通過重寫 equals 方法,你將申明一些對象與其他對象相等,但是原始的 hashCode 方法將所有的對象看做是不同的。所以你將會有不同哈希碼的相同對象。例如,在 HashMap 中調用 contains 方法將會返回 false,即使這個對象已經被添加。

怎樣寫一個好的 hashCode 方法不在這篇文章的范圍內,在 Joshua Bloch 很受歡迎的書《Effective Java》中被很好的闡釋,Java 開發人員的書架上不應缺少這本書。

 

【你的項目需要專業意見嗎?我們的 Developer Support 會為你解決問題。|在我們的 Software Craftsmanship 頁面上尋找關于怎樣編寫簡潔代碼的更多提示?!?/p>

 

為了安全起見,讓 Eclipse IDE 一次產生 equals 和 hashCode 方法: Source > Generate hashCode() and equals()….

 

 

為了保護你自己,你還可以配置 Eclipse 來檢測實現了 equals 方法但是沒有實現 hashCode 方法的類,并顯示錯誤。不幸的是,此選項默認是指為“忽略”:PReferences > Java >Compiler > Errors/Warnings,然后用快速篩選器來搜索“hashcode”:

 

 

更新:正如 laurent 指出,equalsverifier 是一個強大的工具,它用來驗證 hashCode 和 equals 方法的約定。您應該考慮在您的單元測試中使用它。

 

哈希碼沖突

 

任何時候,兩個不同對象有相同的哈希碼,我們稱之為沖突。沖突不要緊,它只是意味著有多個對象在同一個空間里,所以 HashMap 會再檢查一遍來找正確的對象。大量的沖突將會降低系統的性能,但是它們不會導致錯誤的結果。

 

但是如果你誤認為哈希碼是一個對象唯一的句柄,例如使用它作為Map的key,你有時會得到錯誤的對象。因為雖然沖突很罕見,但他們是不可避免的。例如,字符“Aa”和“BB”產生相同的哈希碼:2112。因此:

 

2. 永遠不要把哈希碼誤用作一個key

 

你可能會反對,不像打印機的類型例子,在 Java 中,有 4,294,967,296 的空間(2^32 個可能的整型值)。40億的插槽,發生沖突似乎是極不可能的對嗎?

 

 

事實證明它不是不太可能。這是令人驚訝的沖突:請想象一下在一個房間里有 23 個隨機的人。你覺得兩個人是同一天生日的幾率有多大 ?很低,因為一年有 365 天嗎?事實上,幾率是 50% 左右!50 個人是保守的估計。這個現象稱為生日悖論。應用到哈希碼,這意味著在 77163 個不同的對象中,有 50% 的可能性發生沖突–假設你有一個理想的哈希的函數,均勻地把對象分布在所有可用的空間里面。

 

例如:

 

安然公司的電子郵件集包含 520,924 封電子郵件。計算電子郵件內容字符串的哈希碼時,我發現 50 對(甚至是 2 個三元組)不同的電子郵件有著相同的哈希碼。對于五十萬個字符串,這是一個很好的結果。但是這里的信息是:如果你有很多數據元素,沖突就會發生。如果你正在使用哈希碼作為 key,你不會立即注意到你的錯誤。但是少數人會收到錯誤的郵件。

 

哈希碼可變

 

最后,在哈希碼的契約中,有一個很重要的細節是相當讓人吃驚的:hashCode 并不保證在不同的應用執行中得到相同的結果。讓我們看一看 Java 文檔:

 

在一次 Java 應用的執行中,對于同一個對象,hashCode 方法必須始終返回相同的整數,但這整數不反映對象是否被修改(equals 比較)的信息。同一個應用的不同執行,該整數不必保持一致。

 

事實上,這是不常見的,一些類庫中的類甚至指定它們用于計算哈希碼的精確公式(例如字符串)。對于這些類,哈希碼總是會相同。雖然大部分的哈希碼的實現提供穩定的值,但你不能依賴于這一點。正如這篇文章指出的,有些類庫在不同進程中會返回不同的哈希值,這有的時候會讓人困惑。谷歌的 Protocol Buffers 就是一個例子。

 

因此,你不應該在分布式應用程序中使用哈希碼。一個遠程對象可能與本地對象有不同的哈希碼,即使這兩個對象是相等的。

 

3. 在分布式應用中不要使用哈希碼

 

此外,你應該意識到從一個版本到另一個版本哈希碼的功能實現可能會更改。因此您的代碼不應該依賴于任何特定的哈希碼值。例如,你不應該使用哈希碼來持久化狀態。下次你運行程序的時候,“相同”對象的哈希碼可能不同。

最好的建議可能是:完全不使用哈希碼,除非你自己創造了基于哈希的算法。

 

一種替代方法:SHA1

 

你可能知道加密的哈希碼 SHA1 有時被用來標識對象(例如,git這樣做)。這也是不安全嗎?不。SHA1 使用 160 位密鑰,這使得沖突幾乎是不可能的。即使有很多對象,在這個空間發生沖突的幾率遠遠低于一顆流星撞到你正在執行程序的電腦的幾率。這篇文章對沖突的概率作了很好的概述。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩黄色av网站| 国产一区二区三区免费视频| 97视频在线观看成人| 欧美日韩亚洲系列| 综合国产在线视频| 亚洲xxxx18| 国产精品久久久久久久7电影| 国产91成人在在线播放| www.午夜精品| 色多多国产成人永久免费网站| 91国内揄拍国内精品对白| 欧美精品免费在线观看| 精品久久久久久中文字幕| 欧美电影免费播放| 亚洲日本aⅴ片在线观看香蕉| 成人激情春色网| 2019国产精品自在线拍国产不卡| 91成人在线播放| 热久久美女精品天天吊色| 色狠狠久久aa北条麻妃| 中文字幕亚洲情99在线| 欧美日韩性视频在线| 91精品综合视频| 97精品免费视频| 亚洲精品丝袜日韩| 日韩欧美在线免费观看| 91精品视频一区| 亚洲精品久久久久久久久久久| 色小说视频一区| 性欧美xxxx| 一本一本久久a久久精品综合小说| 欧美激情免费观看| 欧美激情18p| 欧美天堂在线观看| 在线视频免费一区二区| 91精品国产综合久久香蕉| 青青草成人在线| 狠狠久久亚洲欧美专区| 亚洲欧美日韩网| 国语自产精品视频在线看| 亚洲国产91精品在线观看| 欧美色xxxx| 欧美野外猛男的大粗鳮| 日韩高清有码在线| 亚洲精品久久久久久下一站| 久久国产精品免费视频| 欧美大片免费观看| 国产这里只有精品| 成人有码在线播放| 久久影院资源站| 久久国产精品久久国产精品| 97在线视频国产| 欧美成人一二三| 日韩精品视频在线免费观看| 国产精品情侣自拍| 日韩精品中文字幕在线观看| 亚洲久久久久久久久久久| 亚洲图片欧美日产| 亚洲的天堂在线中文字幕| 日韩高清免费观看| 久久91亚洲精品中文字幕| 欧美性猛交xxxx乱大交| 色综合久久88| 欧美日韩一区二区在线播放| 国产精品永久免费视频| 91色琪琪电影亚洲精品久久| 亚洲欧美日韩国产中文专区| 欧洲亚洲女同hd| 日韩av在线网页| 亚洲国内精品在线| 97精品在线观看| 日韩欧美中文字幕在线播放| 日本精品中文字幕| 一区二区三区四区在线观看视频| 操人视频在线观看欧美| 免费99精品国产自在在线| 国内精品久久久久影院 日本资源| 久久伊人免费视频| 亚洲无av在线中文字幕| 国产成人拍精品视频午夜网站| 欧美精品福利在线| 亚洲美女在线视频| 久久这里有精品视频| 国产a∨精品一区二区三区不卡| 国产欧亚日韩视频| 亚洲欧洲第一视频| 欧美视频在线观看 亚洲欧| 亚洲国产精品女人久久久| 欧美一区二区三区免费视| 日韩一区二区三区国产| 国产精品久久久久久久天堂| 日韩欧美国产中文字幕| 久久久久久久久91| 国产精品久久久久久久av电影| 欧美精品一二区| 亚洲精品国产精品久久清纯直播| 久久精品在线播放| 亚洲欧美日本另类| 国产精品一区二区久久国产| 欧美亚洲国产日本| 欧美性xxxxxxxxx| 欧美国产日韩一区二区在线观看| 日韩精品亚洲视频| 国产v综合ⅴ日韩v欧美大片| 一区二区三区美女xx视频| 97视频在线免费观看| 欧美日韩激情网| 久久精品成人欧美大片| 成人网址在线观看| 夜色77av精品影院| 日韩精品极品视频免费观看| 亚洲最新av在线网站| 久久久久久久久久久国产| 亚洲a成v人在线观看| 一区二区在线视频播放| 欧美猛少妇色xxxxx| 成人国产精品久久久久久亚洲| 欧美性生交大片免费| 日韩中文字幕第一页| 精品亚洲一区二区| www.久久撸.com| 久久这里有精品视频| 国产精品综合不卡av| 亚洲影院在线看| 欧美性猛交xxxx免费看久久久| 国产成人av网| 欧美在线一级视频| 欧美理论电影网| 欧美电影在线观看完整版| 久久精品视频在线| 狠狠躁18三区二区一区| 992tv在线成人免费观看| 亚洲欧美色图片| 亚洲精品日韩av| 91视频88av| 成人精品视频99在线观看免费| 亚洲国产精品系列| 91精品久久久久久综合乱菊| 国产成人福利网站| 亚洲精品aⅴ中文字幕乱码| 亚洲欧美在线x视频| 国产精品自产拍在线观看| 欧洲一区二区视频| 国产精品一区二区3区| 亚洲天堂开心观看| 久久久免费观看| 国产精品丝袜久久久久久不卡| 日韩精品在线影院| 久久精品视频网站| 庆余年2免费日韩剧观看大牛| 成人黄色av网| 亚洲天堂免费视频| 国产精品美女免费看| 国产精品日韩专区| 国产日韩欧美日韩| 国产男女猛烈无遮挡91| 亚洲国产成人久久| 国产精品久久久久秋霞鲁丝| 日韩av在线导航| 欧美一区二区三区免费视| 2019日本中文字幕| 国产精品一区二区久久| 91热精品视频| 亚洲天堂开心观看|