鴻蒙OS IdentityHashMap

2022-07-25 18:01 更新

IdentityHashMap

java.lang.Object

|---java.util.AbstractMap<K,V&

|---|---java.util.IdentityHashMap<K,V&

public class IdentityHashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Serializable, Cloneable

此類使用哈希表實現(xiàn) Map 接口,在比較鍵(和值)時使用引用相等代替對象相等。 換句話說,在 IdentityHashMap 中,當且僅當 (k1==k2) 時,兩個鍵 k1 和 k2 才被認為相等。 (在正常的 Map 實現(xiàn)(如 HashMap)中,當且僅當 (k1==null ? k2==null : k1.equals(k2)) 時,才認為兩個鍵 k1 和 k2 相等。)

這個類不是一個通用的 Map 實現(xiàn)! 雖然這個類實現(xiàn)了 Map 接口,但它故意違反了 Map 的一般合同,該合同要求在比較對象時使用 equals 方法。 此類僅在需要引用相等語義的極少數(shù)情況下使用。

此類的典型用途是保留拓撲的對象圖轉(zhuǎn)換,例如序列化或深度復(fù)制。 要執(zhí)行這樣的轉(zhuǎn)換,程序必須維護一個“節(jié)點表”來跟蹤所有已處理的對象引用。 節(jié)點表不能等同于不同的對象,即使它們碰巧相等。 此類的另一個典型用途是維護代理對象。 例如,調(diào)試工具可能希望為被調(diào)試程序中的每個對象維護一個代理對象。

此類提供所有可選的映射操作,并允許空值和空鍵。 此類不保證 map 的順序; 特別是,它不保證訂單會隨著時間的推移保持不變。

此類為基本操作(get 和 put)提供恒定時間性能,假設(shè)系統(tǒng)身份哈希函數(shù) (System#identityHashCode(Object)) 將元素正確地分散在桶中。

此類有一個調(diào)整參數(shù)(影響性能但不影響語義):預(yù)期的最大大小。此參數(shù)是映射預(yù)計持有的鍵值映射的最大數(shù)量。在內(nèi)部,此參數(shù)用于確定最初包含哈希表的桶數(shù)。未指定預(yù)期的最大大小和桶數(shù)之間的精確關(guān)系。

如果映射的大?。ㄦI值映射的數(shù)量)充分超過預(yù)期的最大大小,則增加桶的數(shù)量。增加桶的數(shù)量(“重新散列”)可能相當昂貴,因此創(chuàng)建具有足夠大的預(yù)期最大大小的身份散列映射是值得的。另一方面,對集合視圖的迭代需要的時間與哈希表中的桶數(shù)成正比,因此如果您特別關(guān)心迭代性能或內(nèi)存使用情況,則不要將預(yù)期的最大大小設(shè)置得太高。

請注意,此實現(xiàn)不同步。如果多個線程同時訪問一個身份哈希圖,并且至少有一個線程在結(jié)構(gòu)上修改了該 map,則必須在外部進行同步。 (結(jié)構(gòu)修改是添加或刪除一個或多個映射的任何操作;僅更改與實例已包含的鍵關(guān)聯(lián)的值不是結(jié)構(gòu)修改。)這通常通過在自然封裝映射的某個對象上同步來完成.如果不存在這樣的對象,則應(yīng)使用 Collections#synchronizedMap 方法 “wrapped” map。這最好在創(chuàng)建時完成,以防止對地圖的意外不同步訪問:

   Map m = Collections.synchronizedMap(new IdentityHashMap(...));

由此類的所有“集合視圖方法”返回的集合的迭代器方法返回的迭代器是快速失敗的:如果在創(chuàng)建迭代器后的任何時間對映射進行結(jié)構(gòu)修改,除了通過迭代器自己的刪除之外的任何方式方法,迭代器將拋出 ConcurrentModificationException。因此,面對并發(fā)修改,迭代器快速而干凈地失敗,而不是在未來不確定的時間冒任意的、非確定性的行為。

請注意,不能保證迭代器的快速失敗行為,因為一般來說,在存在不同步的并發(fā)修改的情況下,不可能做出任何硬保證。快速失敗的迭代器會盡最大努力拋出 ConcurrentModificationException。因此,編寫一個依賴于這個異常的正確性的程序是錯誤的:故障快速迭代器應(yīng)該只用于檢測錯誤。

實施說明:這是一個簡單的線性探針哈希表,如 Sedgewick 和 Knuth 的文本中所述。該數(shù)組交替保存鍵和值。 (與使用單獨的數(shù)組相比,這對于大型表具有更好的局部性。)對于許多 JRE 實現(xiàn)和操作混合,此類將產(chǎn)生比 HashMap(使用鏈接而不是線性探測)更好的性能。

此類是 Java 集合框架的成員。

嵌套類摘要

從類 java.util.AbstractMap 繼承的嵌套類/接口
AbstractMap.SimpleEntryK,V, AbstractMap.SimpleImmutableEntryK,V
從接口 java.util.Map 繼承的嵌套類/接口
Map.EntryK,V

構(gòu)造函數(shù)摘要

構(gòu)造函數(shù) 描述
IdentityHashMap() 構(gòu)造一個具有默認預(yù)期最大大小 (21) 的新的空身份哈希映射。
IdentityHashMap(int expectedMaxSize) 構(gòu)造一個具有指定預(yù)期最大大小的新空映射。
IdentityHashMap(Map<? extends K,? extends V> m) 構(gòu)造一個新的身份哈希映射,其中包含指定映射中的鍵值映射。

方法總結(jié)

修飾符和類型 方法 描述
void clear() 從此 map 中刪除所有映射。
Object clone() 返回此身份哈希映射的淺表副本:鍵和值本身沒有被克隆。
boolean containsKey(Object key) 測試指定的對象引用是否是此身份哈希映射中的鍵。
boolean containsValue(Object value) 測試指定的對象引用是否是此標識哈希映射中的值。
SetMap.EntryK,V entrySet() 返回此映射中包含的映射的 Set 視圖。
boolean equals(Object o) 比較指定對象與此映射是否相等。
void forEach(BiConsumer<? super K,? super V> action) 對該映射中的每個條目執(zhí)行給定的操作,直到處理完所有條目或該操作引發(fā)異常。
V get(Object key) 返回指定鍵映射到的值,如果此映射不包含該鍵的映射,則返回 null。
int hashCode() 返回此 map 的哈希碼值。
boolean isEmpty() 如果此身份哈希映射不包含鍵值映射,則返回 true。
SetK keySet() 返回此映射中包含的鍵的基于身份的集合視圖。
V put(K key, V value) 將指定值與此身份哈希映射中的指定鍵相關(guān)聯(lián)。
void putAll(Map<? extends K,? extends V> m) 將所有映射從指定映射復(fù)制到此映射。
V remove(Object key) 如果存在,則從此映射中刪除此鍵的映射。
void replaceAll(BiFunction<? super K,? super V,? extends V> function) 將每個條目的值替換為對該條目調(diào)用給定函數(shù)的結(jié)果,直到所有條目都已處理或該函數(shù)引發(fā)異常。
int size() 返回此身份哈希映射中的鍵值映射的數(shù)量。
CollectionV values() 返回此映射中包含的值的集合視圖。
從類 java.util.AbstractMap 繼承的方法
toString
從接口 java.util.Map 繼承的方法
compute, computeIfAbsent, computeIfPresent, getOrDefault, merge, putIfAbsent, remove, replace, replace
從類 java.lang.Object 繼承的方法
finalize, getClass, notify, notifyAll, wait, wait, wait

構(gòu)造函數(shù)詳細信息

IdentityHashMap

public IdentityHashMap()

構(gòu)造一個具有默認預(yù)期最大大小 (21) 的新的空身份哈希映射。

IdentityHashMap

public IdentityHashMap(int expectedMaxSize)

構(gòu)造一個具有指定預(yù)期最大大小的新空映射。 將超過預(yù)期數(shù)量的鍵值映射放入映射可能會導(dǎo)致內(nèi)部數(shù)據(jù)結(jié)構(gòu)增長,這可能會有些耗時。

參數(shù):

參數(shù)名稱 參數(shù)描述
expectedMaxSize map 的預(yù)期最大尺寸

Throws:

Throw名稱 Throw描述
IllegalArgumentException 如果 expectedMaxSize 為負

IdentityHashMap

public IdentityHashMap(Map<? extends K,? extends V> m)

構(gòu)造一個新的身份哈希映射,其中包含指定映射中的鍵值映射。

參數(shù):

參數(shù)名稱 參數(shù)描述
m 要將其映射放置到此 map 中的 map

Throws:

Throw名稱 Throw描述
NullPointerException 如果指定的 map 為空

方法詳情

size

public int size()

返回此身份哈希映射中的鍵值映射的數(shù)量。

指定者:

接口 MapK,V 中的大小

覆蓋:

AbstractMapK,V 類中的大小

返回:

此映射中的鍵值映射的數(shù)量

isEmpty

public boolean isEmpty()

如果此身份哈希映射不包含鍵值映射,則返回 true。

指定者:

接口 MapK,V 中的 isEmpty

覆蓋:

AbstractMapK,V 類中的 isEmpty

返回:

如果此身份哈希映射不包含鍵值映射,則為 true

get

public V get(Object key)

返回指定鍵映射到的值,如果此映射不包含該鍵的映射,則返回 null。

更正式地說,如果此映射包含從鍵 k 到值 v 的映射,使得 (key == k),則此方法返回 v; 否則返回null。 (最多可以有一個這樣的映射。)

返回值為 null 并不一定表示該映射不包含該鍵的映射; 映射也可能將鍵顯式映射為空。 containsKey 操作可用于區(qū)分這兩種情況。

指定者:

進入接口 MapK,V

覆蓋:

進入類 AbstractMapK,V

參數(shù):

參數(shù)名稱 參數(shù)描述
key 要返回其關(guān)聯(lián)值的鍵

返回:

指定鍵映射到的值,如果此映射不包含該鍵的映射,則為 null

containsKey

public boolean containsKey(Object key)

測試指定的對象引用是否是此身份哈希映射中的鍵。

指定者:

containsKey 在接口 MapK,V

覆蓋:

類 AbstractMapK,V 中的 containsKey

參數(shù):

參數(shù)名稱 參數(shù)描述
key 可能的 key

返回:

如果指定的對象引用是此映射中的鍵,則為 true

containsValue

public boolean containsValue(Object value)

測試指定的對象引用是否是此標識哈希映射中的值。

指定者:

接口 MapK,V 中的 containsValue

覆蓋:

類 AbstractMapK,V 中的 containsValue

參數(shù):

參數(shù)名稱 參數(shù)描述
value 要測試其在此映射中的存在的值

返回:

如果此映射將一個或多個鍵映射到指定的對象引用,則為 true

put

public V put(K key, V value)

將指定值與此身份哈希映射中的指定鍵相關(guān)聯(lián)。 如果映射先前包含鍵的映射,則替換舊值。

指定者:

放入接口 MapK,V

覆蓋:

放入類 AbstractMapK,V

參數(shù):

參數(shù)名稱 參數(shù)描述
key 與指定值關(guān)聯(lián)的鍵
value 要與指定鍵關(guān)聯(lián)的值

返回:

與 key 關(guān)聯(lián)的前一個值,如果沒有 key 映射,則返回 null。 (返回 null 還可以指示映射先前將 null 與 key 關(guān)聯(lián)。)

putAll

public void putAll(Map<? extends K,? extends V> m)

將所有映射從指定映射復(fù)制到此映射。 這些映射將替換此映射對當前指定映射中的任何鍵的任何映射。

指定者:

putAll在接口MapK,V中

覆蓋:

putAll 在類 AbstractMapK,V

參數(shù):

參數(shù)名稱 參數(shù)描述
m 要存儲在此 map 中的映射

Throws:

Throw名稱 Throw描述
NullPointerException 如果指定的 map 為空

remove

public V remove(Object key)

如果存在,則從此映射中刪除此鍵的映射。

指定者:

在接口 MapK,V 中刪除

覆蓋:

在類 AbstractMapK,V 中刪除

參數(shù):

參數(shù)名稱 參數(shù)描述
key 要從映射中刪除其映射的鍵

返回:

與 key 關(guān)聯(lián)的前一個值,如果沒有 key 映射,則返回 null。 (返回 null 還可以指示映射先前將 null 與 key 關(guān)聯(lián)。)

clear

public void clear()

從此地圖中刪除所有映射。 此調(diào)用返回后,map 將為空。

指定者:

在界面 MapK,V 中清除

覆蓋:

在類 AbstractMapK,V 中清除

equals

public boolean equals(Object o)

比較指定對象與此映射是否相等。 如果給定對象也是一個映射并且兩個映射表示相同的對象引用映射,則返回 true。 更正式地說,這個映射等于另一個映射 m 當且僅當 this.entrySet().equals(m.entrySet())。

由于此貼圖基于引用相等的語義,如果將此貼圖與法線貼圖進行比較,則可能違反 Object.equals 合約的對稱性和傳遞性要求。 但是,可以保證在 IdentityHashMap 實例中持有 Object.equals 合約。

指定者:

接口 MapK,V 中的等于

覆蓋:

類 AbstractMapK,V 中的等于

參數(shù):

參數(shù)名稱 參數(shù)描述
o 要與此 map 比較是否相等的對象

返回:

如果指定的對象等于此 map,則為 true

hashCode

public int hashCode()

返回此 map 的哈希碼值。 映射的哈希碼定義為映射的 entrySet() 視圖中每個條目的哈希碼的總和。 這確保了 m1.equals(m2) 意味著 m1.hashCode()==m2.hashCode() 對于任何兩個 IdentityHashMap 實例 m1 和 m2,正如 Object#hashCode 的一般合同所要求的那樣。

由于此映射的 entrySet 方法返回的集合中 Map.Entry 實例的基于引用相等的語義,如果兩個對象之一有可能違反上一段中提到的 Object.hashCode 的合同要求 正在比較的是一個 IdentityHashMap 實例,另一個是法線貼圖。

指定者:

接口 MapK,V 中的 hashCode

覆蓋:

AbstractMapK,V 類中的 hashCode

返回:

此 map 的哈希碼值

clone

public Object clone()

返回此身份哈希映射的淺表副本:鍵和值本身沒有被克隆。

覆蓋:

在類 AbstractMapK,V 中克隆

返回:

這張 map 的淺拷貝

keySet

public SetK keySet()

返回此映射中包含的鍵的基于身份的集合視圖。集合由 map 支持,因此對 map 的更改會反映在集合中,反之亦然。如果在對集合進行迭代時修改了映射,則迭代的結(jié)果是不確定的。該集合支持元素移除,即通過 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 方法從映射中移除相應(yīng)的映射。它不支持 add 或 addAll 方法。

雖然此方法返回的對象實現(xiàn)了 Set 接口,但它不遵守 Set 的一般約定。與其支持映射一樣,此方法返回的集合將元素相等定義為引用相等而不是對象相等。這會影響其 contains、remove、containsAll、equals 和 hashCode 方法的行為。

僅當指定對象是包含與返回集合完全相同的對象引用的集合時,返回集合的 equals 方法才返回 true。如果將此方法返回的集合與正常集合進行比較,則可能違反 Object.equals 合約的對稱性和傳遞性要求。但是,保證 Object.equals 合約在此方法返回的集合中保持不變。

返回集合的 hashCode 方法返回集合中元素的標識哈希碼之和,而不是它們的哈希碼之和。這是通過更改 equals 方法的語義來強制執(zhí)行的,以便在此方法返回的集合中強制執(zhí)行 Object.hashCode 方法的一般合同。

指定者:

接口 MapK,V 中的 keySet

覆蓋:

AbstractMapK,V 類中的 keySet

返回:

此映射中包含的鍵的基于身份的集合視圖

values

public CollectionV values()

返回此映射中包含的值的集合視圖。集合由 map 支持,因此對 map 的更改會反映在集合中,反之亦然。如果在對集合進行迭代時修改了映射,則迭代的結(jié)果是不確定的。該集合支持元素移除,即通過 Iterator.remove、Collection.remove、removeAll、retainAll 和 clear 方法從映射中移除相應(yīng)的映射。它不支持 add 或 addAll 方法。

雖然此方法返回的對象實現(xiàn)了 Collection 接口,但它不遵守 Collection 的一般約定。與其支持映射一樣,此方法返回的集合將元素相等定義為引用相等而不是對象相等。這會影響其 contains、remove 和 containsAll 方法的行為。

指定者:

接口 MapK,V 中的值

覆蓋:

AbstractMapK,V 類中的值

返回:

此 map 中包含的值的集合視圖

entrySet

public SetMap.EntryK,V entrySet()

返回此映射中包含的映射的 Set 視圖。 返回集中的每個元素都是一個基于引用相等的 Map.Entry。 集合由 map 支持,因此對 map 的更改會反映在集合中,反之亦然。 如果在對集合進行迭代時修改了映射,則迭代的結(jié)果是不確定的。 該集合支持元素移除,即通過 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 方法從映射中移除相應(yīng)的映射。 它不支持 add 或 addAll 方法。

與支持映射一樣,此方法返回的集合中的 Map.Entry 對象將鍵和值相等定義為引用相等而不是對象相等。這會影響這些 Map.Entry 對象的 equals 和 hashCode 方法的行為?;谝孟嗟鹊?Map.Entry e 等于對象 o 當且僅當 o 是 Map.Entry 并且 e.getKey()==o.getKey() && e.getValue()==o.getValue( )。為了適應(yīng)這些等于語義,hashCode 方法返回 System.identityHashCode(e.getKey()) ^ System.identityHashCode(e.getValue())。

由于此方法返回的集合中 Map.Entry 實例的基于引用相等的語義,如果其中的任何條目可能違反 Object#equals(Object) 合約的對稱性和傳遞性要求該集合與法線貼圖條目進行比較,或者如果此方法返回的集合與一組法線貼圖條目進行比較(例如通過在法線貼圖上調(diào)用此方法返回)。但是,Object.equals 合約保證在基于身份的映射條目之間以及此類條目的集合之間保持不變。

指定者:

接口 MapK,V 中的 entrySet

指定者:

AbstractMapK,V 類中的 entrySet

返回:

此 map 中包含的身份映射的集合視圖

forEach

public void forEach(BiConsumer<? super K,? super V> action)

從接口復(fù)制的描述:map

對該映射中的每個條目執(zhí)行給定的操作,直到處理完所有條目或該操作引發(fā)異常。 除非實現(xiàn)類另有規(guī)定,否則按照條目集迭代的順序執(zhí)行動作(如果指定了迭代順序)。動作拋出的異常將轉(zhuǎn)發(fā)給調(diào)用者。

指定者:

接口 MapK,V 中的 forEach

參數(shù):

參數(shù)名稱 參數(shù)描述
action 為每個條目執(zhí)行的操作

replaceAll

public void replaceAll(BiFunction<? super K,? super V,? extends V> function)

從接口復(fù)制的描述:map

將每個條目的值替換為對該條目調(diào)用給定函數(shù)的結(jié)果,直到所有條目都已處理或該函數(shù)引發(fā)異常。 函數(shù)拋出的異常被轉(zhuǎn)發(fā)給調(diào)用者。

指定者:

接口 MapK,V 中的 replaceAll

參數(shù):

參數(shù)名稱 參數(shù)描述
function 應(yīng)用于每個條目的函數(shù)
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號