Java - The IdentityHashMap Class

Introduction

Hello there, future Java developers! Today, we're going to embark on an exciting journey into the world of Java's IdentityHashMap class. Now, I know what you might be thinking: "Another map class? Didn't we just learn about HashMap?" Well, you're right, but trust me, IdentityHashMap has its own unique flavor that makes it special. Let's dive in!

Java - The IdentityHashMap Class

Class Declaration

First things first, let's look at how we declare an IdentityHashMap:

import java.util.IdentityHashMap;

IdentityHashMap<String, Integer> myMap = new IdentityHashMap<>();

This line of code creates a new IdentityHashMap that will store String keys and Integer values. But what makes it different from a regular HashMap? Well, that's where things get interesting!

Class Constructors

IdentityHashMap comes with four constructors. Let's break them down:

  1. Default constructor:

    IdentityHashMap<String, Integer> map1 = new IdentityHashMap<>();

    This creates an empty IdentityHashMap with a default capacity of 21.

  2. Constructor with initial capacity:

    IdentityHashMap<String, Integer> map2 = new IdentityHashMap<>(100);

    This creates an empty IdentityHashMap with the specified initial capacity.

  3. Constructor with another Map:

    Map<String, Integer> existingMap = new HashMap<>();
    IdentityHashMap<String, Integer> map3 = new IdentityHashMap<>(existingMap);

    This creates an IdentityHashMap with the same mappings as the specified Map.

  4. Constructor with expected maximum size:

    IdentityHashMap<String, Integer> map4 = new IdentityHashMap<>(100, 0.75f);

    This creates an empty IdentityHashMap with the specified expected maximum size and load factor.

Class Methods

Now, let's look at some of the most commonly used methods in IdentityHashMap:

Method Description
put(K key, V value) Associates the specified value with the specified key
get(Object key) Returns the value to which the specified key is mapped
remove(Object key) Removes the mapping for this key if present
clear() Removes all of the mappings from this map
size() Returns the number of key-value mappings in this map
isEmpty() Returns true if this map contains no key-value mappings
containsKey(Object key) Returns true if this map contains a mapping for the specified key
containsValue(Object value) Returns true if this map maps one or more keys to the specified value

Let's see some of these methods in action:

IdentityHashMap<String, Integer> ages = new IdentityHashMap<>();

// Adding key-value pairs
ages.put("Alice", 25);
ages.put("Bob", 30);

// Getting a value
System.out.println("Alice's age: " + ages.get("Alice")); // Output: Alice's age: 25

// Checking if a key exists
System.out.println("Does Charlie exist? " + ages.containsKey("Charlie")); // Output: Does Charlie exist? false

// Removing a key-value pair
ages.remove("Bob");

// Checking the size
System.out.println("Number of entries: " + ages.size()); // Output: Number of entries: 1

Methods Inherited

IdentityHashMap inherits methods from its superclasses and interfaces. Here are some of them:

Inherited From Methods
java.util.AbstractMap clone(), equals(), hashCode(), toString()
java.util.Map entrySet(), keySet(), values()
java.lang.Object finalize(), getClass(), notify(), notifyAll(), wait()

Adding a Key-Value Mapping in an IdentityHashMap Example

Now, let's dive into what makes IdentityHashMap special. Unlike HashMap, which uses the equals() method to compare keys, IdentityHashMap uses reference equality (==). This means two keys are considered equal only if they are the exact same object in memory.

Let's see this in action:

IdentityHashMap<String, String> identityMap = new IdentityHashMap<>();

String key1 = new String("Hello");
String key2 = new String("Hello");

identityMap.put(key1, "World1");
identityMap.put(key2, "World2");

System.out.println("Size of IdentityHashMap: " + identityMap.size());
System.out.println("Value for key1: " + identityMap.get(key1));
System.out.println("Value for key2: " + identityMap.get(key2));

Output:

Size of IdentityHashMap: 2
Value for key1: World1
Value for key2: World2

Surprised? Even though key1 and key2 have the same content ("Hello"), IdentityHashMap treats them as different keys because they are different String objects in memory.

This behavior can be incredibly useful in certain scenarios. For example, imagine you're writing a program to track different versions of a document. Each version might have the same title, but you want to treat them as separate entities. IdentityHashMap would be perfect for this!

In conclusion, IdentityHashMap is like that quirky cousin in the Map family. It looks similar to the others, but it has its own unique way of doing things. Understanding when to use it can make you a more versatile Java programmer.

Remember, in the world of programming, there's no one-size-fits-all solution. Each tool has its place, and knowing when to use IdentityHashMap is another arrow in your quiver of Java knowledge. Keep practicing, stay curious, and happy coding!

Credits: Image by storyset