IdentityHashMap實現Map接口使用哈希表,在比較鍵(和值)時使用reference-equality代替object-equality。此類不是通用 Map 實現。雖然此類實現了 Map 接口,但它故意違反了 Map 的一般契約,該契約要求在比較對象時使用 equals() 方法。當用戶需要通過引用比較對象時使用該類。它屬於java.util包。
IdentityHashMap的特點
- 它遵循引用相等性,而不是使用 equals() 方法,而是使用 == 運算符。
- 它不同步,必須外部同步。
- 迭代器是fail-fast,拋出ConcurrentModificationException嘗試在迭代時進行修改。
- 假設係統身份哈希函數 (System.identityHashCode(Object)) 在存儲桶中正確分散元素,此類為基本操作(獲取和放置)提供恒定時間性能。 IdentityHashMap 不使用 hashCode() 方法,而是使用 System.identityHashCode() 方法。這是一個顯著的區別,因為現在您可以使用可變對象作為 Map 中的鍵,當映射存儲在 IdentityHashMap 中時,其哈希代碼可能會發生變化。
聲明:
public class IdentityHashMap<K,?V> extends AbstractMap<K,?V> implements Map<K,?V>, Serializable, Cloneable
這裏,K 是鍵對象類型,V 是值對象類型。
在Java中,IdentityHashMap是一個實現Map接口的類。它與 HashMap 類類似,主要區別在於 IdentityHashMap 在比較鍵時使用引用相等而不是對象相等。
HashMap 使用 equals() 方法來比較鍵,而 IdentityHashMap 使用 == 運算符來比較鍵。這意味著在 IdentityHashMap 中,當且僅當兩個鍵是同一對象時才被視為相等,而不是其內容相等。
以下是如何在 Java 中使用 IdentityHashMap 的示例:
Java
import java.util.IdentityHashMap;
public class Example {
public static void main(String[] args) {
IdentityHashMap<String, Integer> identityHashMap = new IdentityHashMap<>();
identityHashMap.put("A", 1);
identityHashMap.put(new String("A"), 2);
System.out.println(identityHashMap.size()); // 2
System.out.println(identityHashMap.get("A")); // 1
}
}
輸出;
2
1
Java 中的 IdentityHashMap 類是 Map 接口的基於哈希表的實現,在比較鍵(和值)時使用 reference-equality 代替 object-equality。
使用 IdentityHashMap 相對於 HashMap 的優點:
- 查找速度更快:由於IdentityHashMap 使用reference-equality 進行比較,因此與使用object-equality 的HashMap 相比,查找速度更快。
- 對於比較對象實例很有用:IdentityHashMap 在您想要比較對象實例而不是對象值的情況下很有用。
使用IdentityHashMap的缺點:
- 使用更多內存:與 HashMap 相比,IdentityHashMap 使用更多內存,因為它需要存儲對對象的引用。
- 不適合所有用例:IdentityHashMap 並不適合所有用例,應謹慎使用,因為它在某些情況下可能會導致意外行為。
IdentityHashMap的層次結構
它實現了可串行化,可克隆,Map接口和擴展抽象映射<K, V>類。
例子:
Java
// Java code to demonstrate IdentityHashMap
import java.util.Map;
import java.util.HashMap;
import java.util.IdentityHashMap;
public class IdentityHashMapExample
{
public static void main(String[] args)
{
// creating an instance of IdentityHashMap
Map<String, String> ihm = new IdentityHashMap<>();
// Putting key and value pair
// in a IdentityHashMap Object
ihm.put("ihmkey","ihmvalue");
ihm.put(new String("ihmkey"),"ihmvalue1");
// ihm.size() will print 2 since it
// compares the objects by reference
System.out.println("Size of IdentityHashMap--"+ihm.size());
}
}
Size of IdentityHashMap--2
IdentityHashMap 的構造函數
我們可以通過兩種方式創建IdentityHashMap的實例:
IdentityHashMap<K, V> ihm = new IdentityHashMap<K, V>(); (or) Map<K, V> hm = new IdentityHashMap<K, V>();
1. IdentityHashMap():構造一個具有默認預期最大大小的新的空身份哈希映射。
IdentityHashMap<K, V> ihm = new IdentityHashMap<K, V>();
2. IdentityHashMap(int ExpectedMaxSize):構造一個具有指定預期最大大小的新的空映射。
IdentityHashMap<K, V> ihm = new IdentityHashMap(int expectedMaxSize);
3. IdentityHashMap(Map m):構造一個新的身份哈希映射,其中包含指定映射中的鍵值映射。
IdentityHashMap<K, V> ihm = new IdentityHashMap(Map m);
IdentityHashMap 的基本操作
1. 添加元素
要將映射插入或添加到 IdentityHashMap,我們有 put() 和 putAll() 方法。 put()可以將特定的鍵及其映射的值插入到特定的映射中。如果傳遞現有鍵,則先前的值將被新值替換。 putAll() 將所有元素(即映射)從一個映射複製到另一個映射。
Java
// Java code to illustrate
// adding elements to IdentityHashMap
import java.util.*;
public class AddingElementsToIdentityHashMap {
public static void main(String[] args)
{
// Creating an empty IdentityHashMap
Map<Integer, String> identity_hash
= new IdentityHashMap<Integer, String>();
// Mapping string values to int keys
// using put() method
identity_hash.put(10, "Geeks");
identity_hash.put(15, "4");
identity_hash.put(20, "Geeks");
identity_hash.put(25, "Welcomes");
identity_hash.put(30, "You");
// Displaying the IdentityHashMap
System.out.println("Initial Mappings are: "
+ identity_hash);
// Inserting existing key along with new value
// previous value gets returned and stored in
// returned_value
String returned_value
= (String)identity_hash.put(20, "All");
// Verifying the returned value
System.out.println("Returned value is: "
+ returned_value);
// Displaying the new map
System.out.println("New map is: " + identity_hash);
// Creating a new Identityhash map and copying
Map<Integer, String> new_Identityhash_map
= new IdentityHashMap<Integer, String>();
new_Identityhash_map.putAll(identity_hash);
// Displaying the final IdentityHashMap
System.out.println("The new map: "
+ new_Identityhash_map);
}
}
Initial Mappings are: {30=You, 10=Geeks, 15=4, 25=Welcomes, 20=Geeks} Returned value is: Geeks New map is: {30=You, 10=Geeks, 15=4, 25=Welcomes, 20=All} The new map: {30=You, 10=Geeks, 15=4, 25=Welcomes, 20=All}
2. 刪除元素
要刪除映射,我們使用IdentityHashMap remove(),IdentityHashMap 類的內置方法,用於從映射中刪除任何特定鍵的映射。
Java
// Java code to illustrate removing
// elements from IdentityHashMap
import java.util.*;
public class RemovingMappingsFromIdentityHashMap {
public static void main(String[] args)
{
// Creating an empty IdentityHashMap
Map<Integer, String> Identity_hash = new
IdentityHashMap<Integer, String>();
// Mapping string values to int keys
Identity_hash.put(10, "Geeks");
Identity_hash.put(15, "4");
Identity_hash.put(20, "Geeks");
Identity_hash.put(25, "Welcomes");
Identity_hash.put(30, "You");
// Displaying the IdentityHashMap
System.out.println("Initial Mappings are: " +
Identity_hash);
// Removing the existing key mapping
String returned_value =
(String)Identity_hash.remove(20);
// Verifying the returned value
System.out.println("Returned value is: " +
returned_value);
// Displaying the new map
System.out.println("New map is: " + Identity_hash);
}
}
Initial Mappings are: {30=You, 10=Geeks, 15=4, 25=Welcomes, 20=Geeks} Returned value is: Geeks New map is: {30=You, 10=Geeks, 15=4, 25=Welcomes}
3. 訪問元素
我們可以使用 get() 方法訪問 IdentityHashMap 的元素,下麵給出了示例。
Java
// Java code to illustrate the accessing
// elements from IdentityHashMap
import java.util.*;
public class AccessingElementsFromIdentityHashMap {
public static void main(String[] args)
{
// Creating an empty IdentityHashMap
Map<Integer, String> identity_hash
= new IdentityHashMap<Integer, String>();
// Mapping string values to int keys
identity_hash.put(10, "Geeks");
identity_hash.put(15, "4");
identity_hash.put(20, "Geeks");
identity_hash.put(25, "Welcomes");
identity_hash.put(30, "You");
// Displaying the IdentityHashMap
System.out.println("Initial Mappings are: "
+ identity_hash);
// Getting the value of 25
System.out.println("The Value is: "
+ identity_hash.get(25));
// Getting the value of 10
System.out.println("The Value is: "
+ identity_hash.get(10));
// Using keySet() to get the set view of keys
System.out.println("The set is: " + identity_hash.keySet());
// Using entrySet() to get the set view
System.out.println("The set is: " +
identity_hash.entrySet());
}
}
Initial Mappings are: {30=You, 10=Geeks, 15=4, 25=Welcomes, 20=Geeks} The Value is: Welcomes The Value is: Geeks The set is: [30, 10, 15, 25, 20] The set is: [30=You, 10=Geeks, 15=4, 25=Welcomes, 20=Geeks]
4. 遍曆
我們可以使用 Iterator 接口來遍曆 Collection Framework 的任何結構。由於迭代器使用一種類型的數據,因此我們使用 Entry< ? , ? > 將兩種不同的類型解析為兼容的格式。然後使用 next() 方法打印 IdentityHashMap 的元素。
Java
// Java code to illustrate the
// iterating over IdentityHashmap
import java.util.*;
public class IteratingIdentityHashMap {
public static void main(String[] args)
{
// Creating an empty IdentityHashMap
IdentityHashMap<Integer, String> identity_hash
= new IdentityHashMap<Integer, String>();
// Mapping string values to int keys
identity_hash.put(10, "Geeks");
identity_hash.put(15, "4");
identity_hash.put(20, "Geeks");
identity_hash.put(25, "Welcomes");
identity_hash.put(30, "You");
// Displaying the IdentityHashMap
System.out.println("Initial Mappings are: "
+ identity_hash);
// Create an Iterator over the
// IdentityHashMap
Iterator<IdentityHashMap.Entry<Integer, String> >
itr = identity_hash.entrySet().iterator();
// The hasNext() method is used to check if there is
// a next element The next() method is used to
// retrieve the next element
while (itr.hasNext()) {
IdentityHashMap.Entry<Integer, String> entry
= itr.next();
System.out.println("Key = " + entry.getKey()
+ ", Value = "
+ entry.getValue());
}
}
}
Initial Mappings are: {30=You, 10=Geeks, 15=4, 25=Welcomes, 20=Geeks} Key = 30, Value = You Key = 10, Value = Geeks Key = 15, Value = 4 Key = 25, Value = Welcomes Key = 20, Value = Geeks
已同步IdentityHashMap
如果多個線程同時訪問一個身份哈希映射,並且至少有一個線程在結構上修改了該映射,則必須進行外部同步。 (結構修改是添加或刪除一個或多個映射的任何操作;僅更改與實例已包含的鍵關聯的值不是結構修改。)這通常是通過在自然封裝映射的某個對象上進行同步來完成的。如果不存在這樣的對象,則使用Collections.synchronizedMap方法映射應該是“wrapped”。最好在創建時完成此操作,以防止意外地不同步訪問Map。
Map m = Collections.synchronizedMap(new IdentityHashMap(…));
IdentityHashMap的方法
- K- Map中按鍵的類型。
- V- 映射中映射的值的類型。
METHOD |
DESCRIPTION |
---|---|
IdentityHashMap clear() | 從此Map中刪除所有映射。 |
IdentityHashMap clone() | 返回此身份哈希映射的淺拷貝:鍵和值本身不會被克隆。 |
IdentityHashMap containsKey() | 測試指定的對象引用是否是此身份哈希映射中的鍵。 |
IdentityHashMap containsValue() | 測試指定的對象引用是否是此身份哈希映射中的值。 |
IdentityHashMap entrySet() | 返回此映射中包含的映射的 Set 視圖。 |
IdentityHashMap equals() | 比較指定對象與此映射是否相等。 |
IdentityHashMap get() | 返回指定鍵映射到的值,如果此映射不包含該鍵的映射,則返回 null。 |
IdentityHashMap hashCode() | 返回此映射的哈希代碼值。 |
IdentityHashMap isEmpty() | 如果此身份哈希映射不包含鍵值映射,則返回 true。 |
IdentityHashMap keySet() | 返回此映射中包含的鍵的基於身份的集合視圖。 |
IdentityHashMap put() | 將指定值與此身份哈希映射中的指定鍵相關聯。 |
IdentityHashMap putAll() | 將指定映射中的所有映射複製到此映射。 |
IdentityHashMap remove() | 從此映射中刪除此鍵的映射(如果存在)。 |
IdentityHashMap size() | 返回此身份哈希映射中鍵值映射的數量。 |
IdentityHashMap values() | 返回此映射中包含的值的集合視圖。 |
類 java.util.AbstractMap 中聲明的方法
METHOD |
DESCRIPTION |
---|---|
toString() | 返回此Map的字符串表示形式。 |
接口 java.util.Map 中聲明的方法
METHOD |
DESCRIPTION |
---|---|
計算?(K key, BiFunction<? super K,?? super V,?? extends V> remappingFunction) | 嘗試計算指定鍵及其當前映射值的映射(如果沒有當前映射,則為 null)。 |
computeIfAbsent?(K key, Function<? super K,?? 擴展 V> 映射函數) | 如果指定的鍵尚未與值關聯(或映射為 null),則嘗試使用給定的映射函數計算其值並將其輸入到此映射中,除非 null。 |
computeIfPresent?(K key, BiFunction<? super K,?? super V,?? extends V> remappingFunction) | 如果指定鍵的值存在且非空,則嘗試在給定鍵及其當前映射值的情況下計算新映射。 |
forEach?(BiConsumer<?超級K,??超級V>動作) | 對此映射中的每個條目執行給定的操作,直到處理完所有條目或該操作引發異常。 |
getOrDefault?(對象鍵,V defaultValue) | 返回指定鍵映射到的值,如果此映射不包含該鍵的映射,則返回 defaultValue。 |
合並?(K key, V value, BiFunction<? super V,?? super V,?? extends V> remappingFunction) | 如果指定的鍵尚未與值關聯或與 null 關聯,則將其與給定的非 null 值關聯。 |
putIfAbsent?(K 鍵,V 值) | 如果指定的鍵尚未與值關聯(或映射為 null),則將其與給定值關聯並返回 null,否則返回當前值。 |
刪除?(對象鍵,對象值) | 僅當指定鍵當前映射到指定值時,才刪除該條目。 |
替換?(K鍵,V值) | 僅當指定鍵當前映射到某個值時才替換該條目。 |
替換?(K 鍵,V 舊值,V 新值) | 僅當當前映射到指定值時才替換指定鍵的條目。 |
ReplaceAll?(BiFunction<? super K,?? super V,?? extends V> 函數) | 將每個條目的值替換為在該條目上調用給定函數的結果,直到處理完所有條目或函數引發異常。 |
IdentityHashMap vsHashMap
- IdentityHashMap 使用相等運算符 “==” 來比較鍵和值,而 HashMap 使用 equals 方法來比較 Map 中的鍵和值。
- 由於 IdentityHashMap 不使用 equals(),因此對於具有昂貴的 equals() 的對象來說,它比 HashMap 更快。
- IdentityHashMap 不要求 key 不可變,因為它不依賴於 equals()。
以下示例程序旨在說明 IdentityHashMap 和 HashMap 實現之間的差異。
Java
// Java code to demonstrate IdentityHashMap and
// illustration of how it is different from HashMap
import java.util.Map;
import java.util.HashMap;
import java.util.IdentityHashMap;
public class IdentityHashMapExample
{
public static void main(String[] args)
{
// Creating HashMap and IdentityHashMap objects
Map<String, String> hm = new HashMap<>();
Map<String, String> ihm = new IdentityHashMap<>();
// Putting key and value in HashMap and IdentityHashMap Object
hm.put("hmkey","hmvalue");
hm.put(new String("hmkey"),"hmvalue1");
ihm.put("ihmkey","ihmvalue");
ihm.put(new String("ihmkey"),"ihmvalue1");
// Print Size of HashMap and WeakHashMap Object
// hm.size() will print 1 since it compares the objects logically
// and both the keys are same
System.out.println("Size of HashMap is : "+hm.size());
// ihm.size() will print 2 since it compares the objects by reference
System.out.println("Size of IdentityHashMap is : "+ihm.size());
}
}
Size of HashMap is : 1 Size of IdentityHashMap is : 2
IdentityHashMap是Java中的一個類,它實現了Map接口並使用引用相等來比較鍵。它與常規 HashMap 類似,但它使用 == 運算符來比較鍵,而不是 equals() 方法。這意味著具有相同內容但不同對象引用的兩個鍵將被視為 IdentityHashMap 中不同的鍵。
以下是如何在 Java 中使用 IdentityHashMap 的示例:
Java
import java.util.IdentityHashMap;
public class IdentityHashMapExample {
public static void main(String[] args) {
IdentityHashMap<String, Integer> map = new IdentityHashMap<>();
// Add key-value pairs to the map
String key1 = new String("key");
String key2 = new String("key");
map.put(key1, 1);
map.put(key2, 2);
// Get values from the map using the same and different keys
System.out.println(map.get(key1)); // Output: 1
System.out.println(map.get(key2)); // Output: 2
System.out.println(map.get(new String("key"))); // Output: null
}
}
1 2 null
在此示例中,我們創建一個 IdentityHashMap 將字符串鍵映射到整數值。我們使用兩個具有相同內容的不同 String 對象將兩個鍵值對添加到映射中。然後,我們使用相同和不同的 String 對象從映射中檢索值。我們發現可以使用具有相同內容的兩個不同鍵從映射中檢索值,但無法使用具有相同內容但不同對象引用的 String 對象檢索值。
請注意,IdentityHashMap 的行為與常規 HashMap 略有不同,並且通常僅在引用相等很重要的某些情況下有用。在大多數情況下,常規的 HashMap 就足夠並且更合適。
相關用法
- Java IdentityHashMap clear()用法及代碼示例
- Java IdentityHashMap clone()用法及代碼示例
- Java IdentityHashMap containsKey()用法及代碼示例
- Java IdentityHashMap containsValue()用法及代碼示例
- Java IdentityHashMap entrySet()用法及代碼示例
- Java IdentityHashMap equals()用法及代碼示例
- Java IdentityHashMap get()用法及代碼示例
- Java IdentityHashMap hashCode()用法及代碼示例
- Java IdentityHashMap isEmpty()用法及代碼示例
- Java IdentityHashMap keySet()用法及代碼示例
- Java IdentityHashMap put()用法及代碼示例
- Java IdentityHashMap putAll()用法及代碼示例
- Java IdentityHashMap remove()用法及代碼示例
- Java IdentityHashMap size()用法及代碼示例
- Java IdentityHashMap values()用法及代碼示例
- Java Integer divideUnsigned()用法及代碼示例
- Java Integer equals()用法及代碼示例
- Java Integer getInteger()用法及代碼示例
- Java Integer longValue()用法及代碼示例
- Java Integer max()用法及代碼示例
- Java Integer min()用法及代碼示例
- Java Integer numberOfLeadingZeros()用法及代碼示例
- Java Integer numberOfTrailingZeros()用法及代碼示例
- Java Integer parseInt()用法及代碼示例
- Java Integer parseUnsignedInt()用法及代碼示例
注:本文由純淨天空篩選整理自佚名大神的英文原創作品 IdentityHashMap class in Java。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。