當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Java IdentityHashMap用法及代碼示例


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 的優點:

  1. 查找速度更快:由於IdentityHashMap 使用reference-equality 進行比較,因此與使用object-equality 的HashMap 相比,查找速度更快。
  2. 對於比較對象實例很有用:IdentityHashMap 在您想要比較對象實例而不是對象值的情況下很有用。

使用IdentityHashMap的缺點:

  1. 使用更多內存:與 HashMap 相比,IdentityHashMap 使用更多內存,因為它需要存儲對對象的引用。
  2. 不適合所有用例:IdentityHashMap 並不適合所有用例,應謹慎使用,因為它在某些情況下可能會導致意外行為。

IdentityHashMap的層次結構

IdentityHashMap in Java

它實現了可串行化,可克隆,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 就足夠並且更合適。



相關用法


注:本文由純淨天空篩選整理自佚名大神的英文原創作品 IdentityHashMap class in Java。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。