国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

Java 理論與實踐: 哈希

2019-11-18 14:41:59
字體:
來源:轉載
供稿:網友

  雖然java語言不直接支持關聯數組 -- 可以使用任何對象作為一個索引的數組 -- 但在根Object類中使用hashCode()方法明確表示期望廣泛使用HashMap(及其前輩Hashtable)。理想情況下基于散列的容器提供有效插入和有效檢索;直接在對象模式中支持散列可以促進基于散列的容器的開發和使用。

定義對象的相等性
Object類有兩種方法來推斷對象的標識:equals()和hashCode()。一般來說,假如您忽略了其中一種,您必須同時忽略這兩種,因為兩者之間有必須維持的至關重要的關系。非凡情況是根據equals() 方法,假如兩個對象是相等的,它們必須有相同的hashCode()值(盡管這通常不是真的)。

特定類的equals()的語義在Implementer的左側定義;定義對特定類來說equals()意味著什么是其設計工作的一部分。Object提供的缺省實施簡單引用下面等式:


public boolean equals(Object obj) { return (this == obj); }


在這種缺省實施情況下,只有它們引用真正同一個對象時這兩個引用才是相等的。同樣,Object提供的hashCode()的缺省實施通過將對象的內存地址對映于一個整數值來生成。由于在某些架構上,地址空間大于int值的范圍,兩個不同的對象有相同的hashCode()是可能的。假如您忽略了hashCode(),您仍然可以使用System.identityHashCode()方法來接入這類缺省值。

忽略 equals() -- 簡單實例
缺省情況下,equals()和hashCode()基于標識的實施是合理的,但對于某些類來說,它們希望放寬等式的定義。例如,Integer類定義equals() 與下面類似:


public boolean equals(Object obj) {
return (obj instanceof Integer
&& intValue() == ((Integer) obj).intValue());
}


在這個定義中,只有在包含相同的整數值的情況下這兩個Integer對象是相等的。結合將不可修改的Integer,這使得使用Integer作為HashMap中的要害字是切實可行的。這種基于值的Equal方法可以由Java類庫中的所有原始封裝類使用,如Integer、Float、Character和Boolean以及String(假如兩個String對象包含相同順序的字符,那它們是相等的)。由于這些類都是不可修改的并且可以實施hashCode()和equals(),它們都可以做為很好的散列要害字。

為什么忽略 equals()和hashCode()?
假如Integer不忽略equals() 和 hashCode()情況又將如何?假如我們從未在HashMap或其它基于散列的集合中使用Integer作為要害字的話,什么也不會發生。但是,假如我們在HashMap中使用這類Integer對象作為要害字,我們將不能夠可靠地檢索相關的值,除非我們在get()調用中使用與put()調用中極其類似的Integer實例。這要求確保在我們的整個程序中,只能使用對應于特定整數值的Integer對象的一個實例。不用說,這種方法極不方便而且錯誤頻頻。

Object的interface contract要求假如根據 equals()兩個對象是相等的,那么它們必須有相同的hashCode()值。當其識別能力整個包含在equals()中時,為什么我們的根對象類需要hashCode()?hashCode()方法純粹用于提高效率。Java平臺設計人員預計到了典型Java應用程序中基于散列的集合類(Collection Class)的重要性--如Hashtable、HashMap和HashSet,并且使用equals()與許多對象進行比較在計算方面非常昂貴。使所有Java對象都能夠支持 hashCode()并結合使用基于散列的集合,可以實現有效的存儲和檢索。

實施equals()和hashCode()的需求
實施equals()和 hashCode()有一些限制,Object文件中列舉出了這些限制。非凡是equals()方法必須顯示以下屬性:

Symmetry:兩個引用,a和 b,a.equals(b) if and only if b.equals(a)
Reflexivity:所有非空引用, a.equals(a)
Transitivity:If a.equals(b) and b.equals(c), then a.equals(c)
Consistency with hashCode():兩個相等的對象必須有相同的hashCode()值
Object的規范中并沒有明確要求equals()和 hashCode() 必須一致 -- 它們的結果在隨后的調用中將是相同的,假設“不改變對象相等性比較中使用的任何信息。”這聽起來象“計算的結果將不改變,除非實際情況如此。”這一模糊聲明通常解釋為相等性和散列值計算應是對象的可確定性功能,而不是其它。

對象相等性意味著什么?
人們很輕易滿足Object類規范對equals() 和 hashCode() 的要求。決定是否和如何忽略equals()除了判定以外,還要求其它。在簡單的不可修值類中,如Integer(事實上是幾乎所有不可修改的類),選擇相當明顯 -- 相等性應基于基本對象狀態的相等性。在Integer情況下,對象的唯一狀態是基本的整數值。

對于可修改對象來說,答案并不總是如此清楚。equals() 和hashCode() 是否應基于對象的標識(象缺省實施)或對象的狀態(象Integer和String)?沒有簡單的答案 -- 它取決于類的計劃使用。對于象List和Map這樣的容器來說,人們對此爭論不已。Java類庫中的大多數類,包括容器類,錯誤出現在根據對象狀態來提供equals()和hashCode()實施。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 黄冈市| 嵊州市| 闽侯县| 白玉县| 光泽县| 美姑县| 昭通市| 古交市| 连山| 四平市| 湖北省| 深泽县| 双流县| 台山市| 霍山县| 洪湖市| 桦川县| 额尔古纳市| 云阳县| 方正县| 武安市| 浠水县| 蓝田县| 新河县| 东海县| 通江县| 历史| 临泉县| 辽宁省| 平塘县| 昌宁县| 广德县| 隆尧县| 四川省| 赤城县| 南康市| 怀化市| 久治县| 武安市| 万山特区| 理塘县|