MAPS
A Map is a data structure used to store elements in a collection of key-value
pairs, where each key is unique, and each key maps to a corresponding
value. Maps are widely used in programming for their efficient data retrieval
based on keys.
Key Features:
Key-Value Pair Storage:
Each entry in a map consists of a key and a value.
Keys are unique; duplicate keys are not allowed.
Values can be duplicated, as they are not constrained by uniqueness.
Efficient Lookup:
Maps provide fast retrieval of values when the key is known.
Mutability:
Maps are generally mutable, meaning keys and values can be added,
updated, or removed after creation.
Types of Maps in Programming:
HashMap (Java) / Dictionary (Python):
Uses a hash table for storage.
Provides constant time complexity for operations on average.
Unordered.
TreeMap (Java):
Based on a red-black tree.
Maintains the keys in sorted order.
LinkedHashMap (Java):
Maintains insertion order or access order.
Combines properties of a hash table and a linked list.
ConcurrentMap (Java):
A thread-safe version of a map for use in concurrent programming.
Operations:
Insertion:
Adding a key-value pair.
Example: map.put(key, value) in Java, or map[key] = value in Python.
Lookup:
Retrieving a value by its key.
Example: map.get(key) in Java, or map[key] in Python.
Deletion:
Removing a key-value pair by its key.
Example: map.remove(key) in Java, or del map[key] in Python.
Traversal:
Iterating over keys, values, or key-value pairs.
Example:
for (Map.Entry<K, V> entry : map.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
Source Code:
import java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
// Create a HashMap
HashMap<String, String> map = new HashMap<>();
int capacity = 16; // Assume the default capacity of HashMap
// Add key-value pairs to the HashMap
System.out.println("Adding Key-Value Pairs:");
addEntry(map, "Alice", "Developer", capacity);
addEntry(map, "Bob", "Designer", capacity);
addEntry(map, "Charlie", "Manager", capacity);
System.out.println("\nRetrieving Values:");
retrieveValue(map, "Alice");
retrieveValue(map, "Bob");
retrieveValue(map, "Diana"); // Key that doesn't exist
System.out.println("\nChecking Existence:");
checkExistence(map, "Charlie"); // Key exists
checkExistence(map, "Diana"); // Key doesn't exist
System.out.println("\nUpdating Value:");
updateEntry(map, "Alice", "Senior Developer", capacity);
retrieveValue(map, "Alice");
System.out.println("\nRemoving Entry:");
removeEntry(map, "Bob", capacity);
System.out.println("\nFinal Map Content:");
displayMap(map, capacity);
}
// Add entry to the map and compute hash code & bucket index
private static void addEntry(HashMap<String, String> map, String key,
String value, int capacity) {
map.put(key, value);
int hashCode = key.hashCode();
int bucketIndex = hashCode & (capacity - 1);
System.out.println("Added Key: " + key);
System.out.println(" Value: " + value);
System.out.println(" Hash Code: " + hashCode);
System.out.println(" Bucket Index: " + bucketIndex);
}
// Retrieve a value from the map
private static void retrieveValue(HashMap<String, String> map, String
key) {
String value = map.get(key);
if (value != null) {
System.out.println("Retrieved Value for Key '" + key + "': " + value);
} else {
System.out.println("Key '" + key + "' not found in the map.");
}
}
// Check if a key exists in the map
private static void checkExistence(HashMap<String, String> map, String
key) {
if (map.containsKey(key)) {
System.out.println("Key '" + key + "' exists in the map.");
} else {
System.out.println("Key '" + key + "' does not exist in the map.");
}
}
// Update an existing entry in the map
private static void updateEntry(HashMap<String, String> map, String key,
String newValue, int capacity) {
if (map.containsKey(key)) {
map.put(key, newValue);
int hashCode = key.hashCode();
int bucketIndex = hashCode & (capacity - 1);
System.out.println("Updated Key: " + key);
System.out.println(" New Value: " + newValue);
System.out.println(" Hash Code: " + hashCode);
System.out.println(" Bucket Index: " + bucketIndex);
} else {
System.out.println("Key '" + key + "' not found. Cannot update.");
}
}
// Remove an entry from the map
private static void removeEntry(HashMap<String, String> map, String key,
int capacity) {
if (map.containsKey(key)) {
int hashCode = key.hashCode();
int bucketIndex = hashCode & (capacity - 1);
map.remove(key);
System.out.println("Removed Key: " + key);
System.out.println(" Hash Code: " + hashCode);
System.out.println(" Bucket Index: " + bucketIndex);
} else {
System.out.println("Key '" + key + "' not found. Cannot remove.");
}
}
// Display the current content of the map
private static void displayMap(HashMap<String, String> map, int capacity)
{
for (String key : map.keySet()) {
String value = map.get(key);
int hashCode = key.hashCode();
int bucketIndex = hashCode & (capacity - 1);
System.out.println("Key: " + key);
System.out.println(" Value: " + value);
System.out.println(" Hash Code: " + hashCode);
System.out.println(" Bucket Index: " + bucketIndex);
}
}
}
Computation of the Hash Code
The actual computation of a hash code for a String in Java using its
formula:
hashCode=s[0]×31(n -1)+s[1]×31(n-2)+…+s[n-1]
Where:
s[i] is the i-th character of the string.
n is the length of the string.
31 is the multiplier (chosen because it is a prime number, which
reduces hash collisions).
Example: Compute the hash code for "ABC"
Step 1: ASCII values of the characters
The ASCII values for "A", "B", and "C" are:
A = 65
B = 66
C = 67
Step 2: Plug into the formula
For the string "ABC", the formula becomes:
hashCode=(65×312)+(66×311)+(67×310)
Step 3: Compute each term
65×312=65×961=62465
66×311=66×31=2046
67×310=67×1=67
Step 4: Add the results
hashCode=62465+2046+67=64578hashCode=62465+2046+67=64578
So, the hash code for "ABC" is 64578.
Code Verification:
public class Main {
public static void main(String[] args) {
String str = "ABC";
int hashCode = str.hashCode();
System.out.println("Hash code for 'ABC': " + hashCode);
}
}
Output:
Hash code for 'ABC': 64578
Computation of the Index
Example: Using Hash Code of "ABC"
Given:
Hash Code: 64578 (calculated earlier for "ABC").
Capacity: Let's assume the bucket array has a default size of 16.
Step 1: Compute capacity - 1
capacity−1=16−1=15capacity−1=16−1=15
Step 2: Compute the bucket index
The formula for the index is:
Index=hashCode & (capacity−1)
Substitute values:
Index=64578 & 15Index=64578&15
Step 3: Convert to binary for bitwise AND
64578 in binary: 1111110011000010
15 in binary: 0000000000001111
Perform the AND operation (keep only bits where both are 1):
1111110011000010 & 0000000000001111 ----------------- 0000000000000010
The result in binary is 10, which equals 2 in decimal.
Step 4: The bucket index
The bucket index is: 2