Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
The IdentityHashMap class
2.1.
Features 
2.2.
Constructors 
2.3.
Functions/Methods
2.4.
Basic Operations
3.
Frequently Asked Questions
4.
Key Takeaways
Last Updated: Mar 27, 2024

IdentityHashMap in Java

Author Yashesvinee V
0 upvote

Introduction

The java.util package provides many functions, utilities and interfaces to build applications and programs in Java. One such utility is the Map interface that helps to map a key to its corresponding value. They are used to search, identify and update elements by their keys. Hash tables are used to store these key-value pairs for easy computation. The keys of a Map and Hash table are unique and cannot be null.

The IdentityHashMap is a class that implements the Map interface using HashTable and is used when the user requires a comparison of objects by reference. For example, two keys, k1 and k2 are considered equal if and only if (k1==k2) in IdentityHashMap. In normal Map implementations like HashMap, two keys k1 and k2 are considered equal if and only if (k1==null ? k2==null : k1.equals(k2)).

Also read, Duck Number in Java and  Hashcode Method in Java

The IdentityHashMap class

Declaration Syntax:

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

 

K - key object type V - value object type

Syntax to create an instance of IdentityHashMap:

IdentityHashMap<K, V> ihm = new IdentityHashMap<K, V>();

OR

Map<K, V> hm = new IdentityHashMap<K, V>();

Features 

  • The class provides all the optional map operations and permits null values and the null key. It does not guarantee that the order of the map will remain constant over time.
     
  • It is used for topology-preserving object graph transformations like serialisation and cloning.
     
  • IdentityHashMap violates the general contract of a Map which states that the comparison of objects must be performed using the equals method.
     
  • It is used when reference-equality semantics are required on key search operations. ‘==’ is used instead of the equals() method.
     
  • Its implementation is not synchronised and has to be done externally.
     
  • Iterators created by the iterator method are fail-fast. If a map is structurally modified at any time after the iterator is created, it throws a ConcurrentModificationException. The iterator fails quickly rather than risking a non-deterministic behaviour at an undetermined time in the future.
     
  • ‘expected maximum size’ is a parameter that stores the maximum number of key-value mappings (internally, the number of buckets comprising the hash table). If the map size exceeds this parameter, the number of buckets increases, which is fairly expensive. This parameter affects performance but not semantics.

Constructors 

  • IdentityHashMap() -

    • It creates a new and empty identity hash map with a default expected maximum size of 21.
       
  • IdentityHashMap(int expectedmaxsize) -

    • It constructs a new and empty map with a given expected maximum size.
       
    • If expectedmaxsize is negative, IllegalArgumentException is thrown.
       
  • IdentityHashMap(Map m) -

    • It constructs a new identity hash map that contains the key-value mappings of a specified map.
       
    • If the Map parameter is null, NullPointerException is thrown.
       
import java.util.*;
public class Main {
 
  public static void main(String[] args)
  {
      // IdentityHashMap() constructor
       Map<Integer, String> identity_hash1 = new IdentityHashMap<Integer, String>();
      
      identity_hash1.put(1, "A");
      identity_hash1.put(2, "B");
              
      System.out.println("Mappings of IdentityHashMap-1 are: "+ identity_hash1);
      
      // IdentityHashMap(int expectedmaxsize) constructor
       Map<Integer, String> identity_hash2 = new IdentityHashMap<Integer, String>(1);

      identity_hash2.put(26, "Z");
      identity_hash2.put(25, "Y");
              
      System.out.println("Mappings of IdentityHashMap-2 are: "+ identity_hash2);

      // IdentityHashMap() constructor
       Map<Integer, String> identity_hash3 = new IdentityHashMap<Integer, String>(identity_hash1);
    
      System.out.println("Mappings of IdentityHashMap-3 are: " + identity_hash3);
      }
}

 

Output:

Mappings of IdentityHashMap-1 are: {1=A, 2=B}
Mappings of IdentityHashMap-2 are: {25=Y, 26=Z}
Mappings of IdentityHashMap-3 are: {1=A, 2=B}


Practice it on online java compiler.

Functions/Methods

Method

Type

Description

clear() void It removes all the mappings from a specified map.
clone() Object It returns a shallow copy of the identity hash map but does not clone its key-value pairs.
containsKey(Object Key) boolean It returns true if the given object is a key in the identity hash map.
containsValue(Object value) boolean It returns true if the given object is a value in the identity hash map.
entrySet() Set<Map.Entry<K,V>> It returns a set-view of all the mappings present in the map.
equals(object o) boolean

It returns true if the given object is also a map and has the same object-reference mappings i.e.

this.entrySet().equals(m.entrySet())

get(Object key) V It returns the value of the given key if it is present in the map else, it returns null.
hashcode() int It returns the hash code value for the map
isEmpty() boolean It returns true if the map contains no key-value pairs.
keySet() Set<K> It returns a set-view of the keys present in the map
put(K key, V value) V It adds a key-value pair to the identity hash map. If the key already exists, then its value is updated.
putAll(Map m)  void It copies all the key-value mappings of a given map and replaces the original content of the map
remove(Object key) V It removes the mapping for a given key if it is present in the map.
size() int It returns the number of key-value pairs in the identity hash map.
values() Collection<V> It returns a collection view of the values present in the map

 

Basic Operations

  • Adding Elements

    • Elements can be added to an Identity hash map by using the put() and putAll() functions.
       
    • As mentioned earlier, put() inserts a specific mapping into the map, while putAll() inserts the entire set of copied mappings from another map.
       
import java.util.*;
 
public class AddToMap {
  
    public static void main(String[] args)
    {
        Map<Integer, String> identity_hash = new IdentityHashMap<Integer, String>();
        
        identity_hash.put(1, "A");
        identity_hash.put(2, "B");
        identity_hash.put(3, "C");
        identity_hash.put(4, "E");
        
        System.out.println("Initial Mappings are: "+ identity_hash);
        
        String returned_value = (String)identity_hash.put(4, "D");

        System.out.println("Final Mappings are: "+ identity_hash);

        Map<Integer, String> new_identity_hash = new IdentityHashMap<Integer, String>();
        new_identity_hash.putAll(identity_hash);

        System.out.println(“ Mappings of second map are: "+ new_identity_hash);
        }
}

 

Output:

Initial Mappings are: {4=E, 1=A, 3=C, 2=B}
Final Mappings are: {4=D, 1=A, 3=C, 2=B}
Mappings of second map are: {4=D, 1=A, 3=C, 2=B}

 

  • Remove elements:

    • The remove() method removes a particular mapping from the identity hash map.
       
    • The clear() method can remove all the mappings present in the map.
       
import java.util.*;
 
public class RemoveFromMap {
  
    public static void main(String[] args)
    {
        Map<Integer, String> identity_hash = new IdentityHashMap<Integer, String>();
        
        identity_hash.put(1, "A");
        identity_hash.put(2, "B");
        identity_hash.put(3, "C");
        identity_hash.put(4, "D");
        
        System.out.println("Initial Mappings are: "+ identity_hash);
        
        String returned_value = (String)identity_hash.remove(4);

        System.out.println("Final Mappings are: "+ identity_hash);

        identity_hash.clear();

        System.out.println("After removing all mappings: "+ identity_hash);
        }
}

 

Output:

Initial Mappings are: {4=E, 1=A, 3=C, 2=B}
Final Mappings are: {1=A, 3=C, 2=B}
After removing all mappings: {}

 

  • Accessing keys and their values:

    • The get() method is used to obtain the value of a specific key.
       
    • The entrySet() is used to get all the mappings of the identity hash map.
       
    • keySet() is used to obtain a set of all the keys in the map.
       
    • values() is used to obtain all the values of the keys in the map.
       
import java.util.*;
 
public class FindInMap {
  
    public static void main(String[] args)
    {
        Map<Integer, String> identity_hash = new IdentityHashMap<Integer, String>();
        
        identity_hash.put(1, "A");
        identity_hash.put(2, "B");
        identity_hash.put(3, "C");
        identity_hash.put(4, "D");
        
        System.out.println("Mappings: "+ identity_hash.entrySet());

        System.out.println("Mapping of 4 is: "+ identity_hash.get(4));

        System.out.println("Keys: "+ identity_hash.keySet());

        System.out.println("Values: "+ identity_hash.values());
        }
}

 

Output:

Mappings: [4=D, 1=A, 3=C, 2=B]
Mapping of 4 is: D
Keys: [4, 1, 3, 2]
Values: [D, A, C, B]

 

  • Traversal

    • The iterator interface is used to traverse an Identity hash map. The next() method is used to print the consecutive elements of the map.
       
import java.util.*;

public class TraverseMap {
 
    public static void main(String[] args)
    {
        Map<Integer, String> identity_hash = new IdentityHashMap<Integer, String>();
        
        identity_hash.put(1, "A");
        identity_hash.put(2, "B");
        identity_hash.put(3, "C");
        identity_hash.put(4, "D");
      
        System.out.println("Initial Mappings are: "+ identity_hash);
        
        Iterator<IdentityHashMap.Entry<Integer, String> >
            itr = identity_hash.entrySet().iterator();

        while(itr.hasNext()) 
        {
            IdentityHashMap.Entry<Integer,String> entry= itr.next();
            System.out.println("Key = "+ entry.getKey()+ ",Value = "+ entry.gatValue());
        }    
      }
}

 

Output:

Initial Mappings are: {4=D, 1=A, 3=C, 2=B}
Key = 4, Value = D
Key = 1, Value = A
Key = 3, Value = C
Key = 2, Value = B

Also see,  Swap Function in Java

Frequently Asked Questions

Q: What is a synchronised IdentityHashMap?

When multiple threads run concurrently to access the same IdentityHashMap, and at least one thread makes modifications to the map’s structure, it must be synchronised externally. This can be done by synchronising an object that encapsulates the map. The Collections.synchronizedMap method is used to ‘wrap’ the map if the object does not exist.

Q: What is the difference between IdentityHashMap and HashMap? 

  • IdentityHashMap violates the Map’s general contract, while a HashMap doesn’t.
     
  • IdentityHashMap uses reference equality, and HashMap uses object equality to compare keys and values.
     
  • An IdentityHashMap does not require the key to be immutable, while the HashMap does.
     
  • IdentityHashMap uses a linear probe hash table, and HashMap uses chaining.

Key Takeaways

Maps, Hash tables, HashMaps, IdentityHashMaps, Dictionaries, etc., involve key-value associations or mappings that are extremely helpful for programmers to build applications. These structures and classes play an essential role in most of today’s software programs. This blog gives an introduction to key-value mappings in Java using the Map interface and IdentityHashMap class. It also covers the features, constructors, methods and basic operations that can be performed using the IdentityHashMap class.

Related Links

Check out the official Coding Ninjas Blog site and visit our Library for more.

Live masterclass