What is IdentityHashMap in Java?
IdentityHashMap implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys and values.
In other words, in an IdentityHashMap
, two keys
k1 and k2 are considered equal if and only if
(k1==k2). 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)).
This class is not a general-purpose Map implementation. While this class implements the Map interface, it intentionally violates Map’s general contract, which mandates the use of the equals method when comparing objects.
This class is designed for use only in the rare cases wherein reference-equality semantics are required.
Here is the topic that will cover in this post.
Java IdentityHashMap class Declaration
The IdentityHashMap
class extends AbstractMap
and implements the Map
interface
. It is similar to
HashMap except that it
uses reference equality when comparing elements. IdentityHashMap
is a generic class that has this
declaration:
public class IdentityHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, java.io.Serializable, Cloneable
Here, K specifies the type of keys, and V specifies the type of values.
Java IdentityHashMap features
- Java IdentityHashMap inherits
AbstractMap
class.- Java IdentityHashMap implements the Map interface.
- Java IdentityHashMap permits one
null
key and multiplenull
values.- Java IdentityHashMap can not be used for primitive types, like int, char, etc. We need to use wrapper classes.
- This class does not guarantee that the order will remain constant over time.
- Java IdentityHashMap is not synchronized.
- Java IdentityHashMap is not thread-safe. You can make thread-safe by doing
Map m = Collections.synchronizedMap(new IdentityHashMap(...));- Java IdentityHashMap implementation provides constant-time performance for the basic operations (get, and put), assuming the hash function disperses the elements properly among the buckets.
- Java IdentityHashMap uses linear-probe hash table. IdentityHashMap performance is better than HashMap (which uses chaining rather than linear-probing).
- The iterators returned by all of this class's "collection view methods" are fail-fast.
Use cases for IdentityHashMap
- A typical use of this class is topology-preserving object graph transformations, such as serialization or deep-copying. To perform such a transformation, a program must maintain a "node table" that keeps track of all the object references that have already been processed. The node table must not equate distinct objects even if they happen to be equal.
- Another typical use of this class is to maintain proxy objects. For example, a debugging facility might wish to maintain a proxy object for each object in the program being debugged.
Java IdentityHashMap constructors
Java IdentityHashMap have five constructors.
Constructor | Description |
---|---|
public IdentityHashMap() | Constructs an empty identity hash map with a default expected maximum size (21). |
public IdentityHashMap(int expectedMaxSize) | Constructs an empty map with the specified expected maximum size. Putting more than the expected number of key-value mappings into the map may cause the internal data structure to grow, which may be somewhat time-consuming. |
public IdentityHashMap(Map<? extends K, ? extends V> m) | Constructs a new identity hash map containing the keys-value mappings in the specified map. |
Below code snippet show example to create IdentityHashMap instances using it's constructors.
IdentityHashMap<Integer, String> identityHashMap1 = new IdentityHashMap<>(); IdentityHashMap<Integer, String> identityHashMap2 = new IdentityHashMap<>(32); IdentityHashMap<Integer, String> identityHashMap3 = new IdentityHashMap<>(identityHashMap1);
Java IdentityHashMap methods
IdentityHashMap
does not provide own method. IdentityHashMap uses the methods of the HashMap.
Example
Here is a simple program of IdentityHashMap.
package com.walking.techie; import java.util.Collection; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; public class IdentityHashMapDemo { public static void main(String[] args) { IdentityHashMap<Integer, String> identityHashMap = new IdentityHashMap<>(); identityHashMap.put(100, "Continue"); identityHashMap.put(200, "OK"); identityHashMap.put(300, "Multiple Choices"); identityHashMap.put(302, "Moved Temporarily"); Integer key = new Integer(400); identityHashMap.put(key, "Bad Request"); identityHashMap.put(401, "Unauthorized"); identityHashMap.put(500, "Server Error"); identityHashMap.put(503, "Service Unavailable"); // size of identityHashMap System.out.println("Size of the identityHashMap : " + identityHashMap.size()); // check identityHashMap is empty or not System.out.println("Is identityHashMap Empty? " + identityHashMap.isEmpty()); // get the value for given Key, compare on reference System.out.println("Http message for HttpStatus code 400 is " + identityHashMap.get(key)); // return null System.out.println("Http message for HttpStatus code 401 is " + identityHashMap.get(401)); // check identityHashMap contain mapping for given key System.out .println("Is identityHashMap contain mapping for HttpStatus code 400 is " + identityHashMap .containsKey(key)); // return false System.out.println("Is identityHashMap contain mapping for HttpStatus code 401 is " + identityHashMap .containsKey(401)); Map<Integer, String> httpStatus = new TreeMap<>(); httpStatus.put(424, "Failed Dependency"); httpStatus.put(504, "Gateway Timeout"); httpStatus.put(409, "Conflict"); // copy all elements of httpStatus to identityHashMap identityHashMap.putAll(httpStatus); // print all the elements of the identityHashMap System.out.println("\n******All elements of the identityHashMap"); for (Integer code : identityHashMap.keySet()) { System.out.println("Http Status Code : " + code + " Http Message : " + identityHashMap.get(code)); } System.out .println("\nSize of the identityHashMap before remove call " + identityHashMap.size()); // remove the mapping from the identityHashMap for given key System.out.println("\nValue of the removed key (503) is : " + identityHashMap.remove(503)); System.out.println("Size of the identityHashMap before after call " + identityHashMap.size()); System.out.println("\nValue of the removed key (400) is : " + identityHashMap.remove(key)); // To check value is present is the identityHashMap System.out.println("\nToo Many Requests is present in identityHashMap : " + identityHashMap .containsValue("Too Many Requests")); System.out.println("Upgrade Required is present in identityHashMap : " + identityHashMap .containsValue("Upgrade Required")); // Get collection view of this identityHashMap Collection<String> httpStatusMessage = identityHashMap.values(); System.out.println("\n *****Http Status message of the collection view*****"); for (String message : httpStatusMessage) { System.out.println("Http Status Message : " + message); } // Display key-value pair of element using EntrySet Set<Entry<Integer, String>> entrySet = identityHashMap.entrySet(); Iterator<Entry<Integer, String>> iterator = entrySet.iterator(); System.out.println("\n *****Display Elements of the identityHashMap using EntrySet*****"); while (iterator.hasNext()) { Entry<Integer, String> entry = iterator.next(); System.out .println("Http Status Code : " + entry.getKey() + " Http Message : " + entry.getValue()); } // create clone of identityHashMap Object clonedHashMap = identityHashMap.clone(); System.out.println("\nCloned identityHashMap : \n" + clonedHashMap); // clear all elements of the identityHashMap identityHashMap.clear(); System.out.println("\nSize of the identityHashMap is " + identityHashMap.size()); } }
Output of above program is shown below:
Size of the identityHashMap : 8 Is identityHashMap Empty? false Http message for HttpStatus code 400 is Bad Request Http message for HttpStatus code 401 is null Is identityHashMap contain mapping for HttpStatus code 400 is true Is identityHashMap contain mapping for HttpStatus code 401 is false ******All elements of the identityHashMap Http Status Code : 300 Http Message : Multiple Choices Http Status Code : 500 Http Message : Server Error Http Status Code : 409 Http Message : Conflict Http Status Code : 400 Http Message : Bad Request Http Status Code : 424 Http Message : Failed Dependency Http Status Code : 302 Http Message : Moved Temporarily Http Status Code : 504 Http Message : Gateway Timeout Http Status Code : 200 Http Message : OK Http Status Code : 100 Http Message : Continue Http Status Code : 401 Http Message : Unauthorized Http Status Code : 503 Http Message : Service Unavailable Size of the identityHashMap before remove call 11 Value of the removed key (503) is : null Size of the identityHashMap before after call 11 Value of the removed key (400) is : Bad Request Too Many Requests is present in identityHashMap : false Upgrade Required is present in identityHashMap : false *****Http Status message of the collection view***** Http Status Message : Multiple Choices Http Status Message : Server Error Http Status Message : Conflict Http Status Message : Failed Dependency Http Status Message : Moved Temporarily Http Status Message : Gateway Timeout Http Status Message : OK Http Status Message : Continue Http Status Message : Unauthorized Http Status Message : Service Unavailable *****Display Elements of the identityHashMap using EntrySet***** Http Status Code : 300 Http Message : Multiple Choices Http Status Code : 500 Http Message : Server Error Http Status Code : 409 Http Message : Conflict Http Status Code : 424 Http Message : Failed Dependency Http Status Code : 302 Http Message : Moved Temporarily Http Status Code : 504 Http Message : Gateway Timeout Http Status Code : 200 Http Message : OK Http Status Code : 100 Http Message : Continue Http Status Code : 401 Http Message : Unauthorized Http Status Code : 503 Http Message : Service Unavailable Cloned identityHashMap : {300=Multiple Choices, 500=Server Error, 409=Conflict, 424=Failed Dependency, 302=Moved Temporarily, 504=Gateway Timeout, 200=OK, 100=Continue, 401=Unauthorized, 503=Service Unavailable} Size of the identityHashMap is 0
Iterate or Traverse over IdentityHashMap
1. Iterating IdentityHashMap in java using iterator and KeySet
package com.walking.techie; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Set; public class IdentityHashMapTraversal { public static void main(String[] args) { IdentityHashMap<Integer, String> identityHashMap = new IdentityHashMap<>(); identityHashMap.put(100, "Continue"); identityHashMap.put(400, "Bad Request"); identityHashMap.put(200, "OK"); identityHashMap.put(500, "Server Error"); identityHashMap.put(300, "Multiple Choices"); // Returns a Set view of the keys contained in this map. Set<Integer> set = identityHashMap.keySet(); // Returns an iterator over the elements in this set. Iterator<Integer> itr = set.iterator(); while (itr.hasNext()) { Integer key = itr.next(); System.out.println("Key=" + key + " Value=" + identityHashMap.get(key)); } } }
Output of above program is shown below:
Key=200 Value=OK Key=300 Value=Multiple Choices Key=500 Value=Server Error Key=400 Value=Bad Request Key=100 Value=Continue
2. Iterating IdentityHashMap in java using EntrySet and Java Iterator
package com.walking.techie; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class IdentityHashMapTraversal { public static void main(String[] args) { IdentityHashMap<Integer, String> identityHashMap = new IdentityHashMap<>(); identityHashMap.put(100, "Continue"); identityHashMap.put(400, "Bad Request"); identityHashMap.put(200, "OK"); identityHashMap.put(500, "Server Error"); identityHashMap.put(300, "Multiple Choices"); // Returns a Set view of the mappings contained in this map. Set<java.util.Map.Entry<Integer, String>> entry = identityHashMap.entrySet(); // Returns an iterator over the elements in this set. Iterator<Entry<Integer, String>> iterator = entry.iterator(); while (iterator.hasNext()) { Map.Entry<Integer, String> entry2 = (Entry<Integer, String>) iterator.next(); System.out.println("Key=" + entry2.getKey() + " Value=" + entry2.getValue()); } } }
Output of above program is shown below:
Key=200 Value=OK Key=300 Value=Multiple Choices Key=500 Value=Server Error Key=400 Value=Bad Request Key=100 Value=Continue
3. Iterating IdentityHashMap in java using EntrySet and Java for loop
package com.walking.techie; import java.util.IdentityHashMap; import java.util.Map.Entry; import java.util.Set; public class IdentityHashMapTraversal { public static void main(String[] args) { IdentityHashMap<Integer, String> identityHashMap = new IdentityHashMap<>(); identityHashMap.put(100, "Continue"); identityHashMap.put(400, "Bad Request"); identityHashMap.put(200, "OK"); identityHashMap.put(500, "Server Error"); identityHashMap.put(300, "Multiple Choices"); Set<Entry<Integer, String>> entrySet = identityHashMap.entrySet(); for (Entry<Integer, String> entry : entrySet) { System.out.println("Key=" + entry.getKey() + " Value=" + entry.getValue()); } } }
Output of above program is shown below:
Key=200 Value=OK Key=300 Value=Multiple Choices Key=500 Value=Server Error Key=400 Value=Bad Request Key=100 Value=Continue
4. Iterating IdentityHashMap in java using KeySet and Java for loop
package com.walking.techie; import java.util.IdentityHashMap; public class IdentityHashMapTraversal { public static void main(String[] args) { IdentityHashMap<Integer, String> identityHashMap = new IdentityHashMap<>(); identityHashMap.put(100, "Continue"); identityHashMap.put(400, "Bad Request"); identityHashMap.put(200, "OK"); identityHashMap.put(500, "Server Error"); identityHashMap.put(300, "Multiple Choices"); for (Integer key : identityHashMap.keySet()) { System.out.println("Key=" + key + " Value=" + identityHashMap.get(key)); } } }
Output of above program is shown below:
Key=200 Value=OK Key=300 Value=Multiple Choices Key=500 Value=Server Error Key=400 Value=Bad Request Key=100 Value=Continue
5. Iterating IdentityHashMap in java using Java 8 forEach and lambda expression
package com.walking.techie; import java.util.IdentityHashMap; public class IdentityHashMapTraversal { public static void main(String[] args) { IdentityHashMap<Integer, String> identityHashMap = new IdentityHashMap<>(); identityHashMap.put(100, "Continue"); identityHashMap.put(400, "Bad Request"); identityHashMap.put(200, "OK"); identityHashMap.put(500, "Server Error"); identityHashMap.put(300, "Multiple Choices"); // using java 8 for each and lambda expression identityHashMap.forEach((k, v) -> { System.out.println("Key=" + k + " Value=" + v); }); } }
Output of above program is shown below:
Key=200 Value=OK Key=300 Value=Multiple Choices Key=500 Value=Server Error Key=400 Value=Bad Request Key=100 Value=Continue
Difference between HashMap and IdentityHashMap
- HashMap uses equals method for comparing keys and values while IdentityHashMap uses equality operator “==” for comparing keys and values inside map.
- IdentityHashMap does not use equals() method so it is comparatively faster than HashMap for object with expensive equals() method.
- IdentityHashMap does not require keys to be immutable as it is not relied on equals() method.
No comments :
Post a Comment