当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。