Java Collection: Map Interface

Reetesh Kumar
6 min readJan 25, 2024

--

Introduction

The Map interface is part of the Java Collections Framework and is used to store data in key-value pairs. An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.

This interface takes the place of the Dictionary class, which is an abstract class rather than an interface. The Map interface provides three collection views, which allow a map’s contents to be viewed as a set of keys, a collection of values, or a set of key-value mappings.

The order of a map is defined as the order in which the iterators on the map’s collection views return their elements. Some map implementations, like the TreeMap class, make specific guarantees as to their order; others, like the HashMap class, do not. The Map interface is not a subtype of the Collection interface and therefore, it behaves a bit differently compared to other collection types.

Key Characteristics Of Map

  1. Associative Array: Map works like an associative array, where each key maps to a specific value.
  2. Uniqueness of Keys: Each key can map to at most one value, meaning duplicate keys are not allowed.
  3. Null Values: Depending on the implementation, Maps can allow null keys and null values.

Implementations of Map Interface

Map Interface implementation class hierarchy:

There are several implementations of the Map interface in Java, each with its unique characteristics:

  1. HashMap: It stores the elements in a hash table. It allows null values and one null key. It’s unordered and offers constant-time performance for basic operations.
  2. TreeMap: Implements a Map based on a Red-Black tree structure. It sorts the elements based on the natural ordering of the keys or by a Comparator provided at map creation time.
  3. LinkedHashMap: Maintains the insertion order of elements. It is slightly slower than HashMap but faster in iteration.
  4. Hashtable: Similar to HashMap, but it’s synchronized and doesn’t allow null keys or values.
  5. EnumMap: A specialized Map implementation for use with enum type keys.

How To Use Map?

In Java, we must import the java.util.Map package to use Map. Once we import the package, here’s how we can create a map.

// Map implementation using HashMap
Map<Key, Value> map = new HashMap<>();

In the above code, we have created a Map named map. We have used the HashMap class to implement the Map interface. Here,

Key: a unique identifier used to associate each element (value) in a map.

Value: elements associated by keys in a map.

Adding Elements

To add an element to a Map, use the put method. If the key already exists, its value is updated; otherwise, a new key-value pair is added.

Map<String, Integer> map = new HashMap<>();
map.put("Apple", 1);
map.put("Banana", 2);

Accessing Elements

Use the get method to retrieve a value using its key.

int value = map.get("Apple"); // Returns 1

Iterating Over a Map

You can iterate over a map’s key set, value collection, or entry set.

// Iterating over keys
for(String key : map.keySet()) {
System.out.println(key);
}

// Iterating over values
for(Integer value : map.values()) {
System.out.println(value);
}

// Iterating over entries
for(Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}

Methods Of Map

The Map interface includes all the methods of the Collection interface. It is because Collection is a super interface of Map. Besides methods available in the Collection interface, the Map interface also includes the following methods:

  1. put(K, V): Inserts the association of a key K and a value V into the map. If the key is already present, the new value replaces the old value.
  2. putAll(): Inserts all the entries from the specified map to this map.
  3. putIfAbsent(K, V): Inserts the association if the key K is not already associated with the value V.
  4. get(K): Returns the value associated with the specified key K. If the key is not found, it returns null.
  5. getOrDefault(K, defaultValue): Returns the value associated with the specified key K. If the key is not found, it returns the defaultValue.
  6. containsKey(K): Checks if the specified key K is present in the map or not.
  7. containsValue(V): Checks if the specified value V is present in the map or not.
  8. replace(K, V): Replace the value of the key K with the new specified value V.
  9. replace(K, oldValue, newValue): Replaces the value of the key K with the new value newValue only if the key K is associated with the value oldValue.
  10. remove(K): Removes the entry from the map represented by the key K.
  11. remove(K, V): Removes the entry from the map that has key K associated with value V.
  12. keySet(): Returns a set of all the keys present in a map.
  13. values(): Returns a set of all the values present in a map.
  14. entrySet(): Returns a set of all the key/value mapping present in a map.

Example Of Map Interface

Scenario: Online Shopping Cart Management

In an e-commerce application, users add products to their shopping cart. You need to keep track of each user’s cart, which contains various products and their quantities.

Implementing with Map Interface: To handle this, we can use a Map to associate each user with their respective shopping cart. Here’s how we can implement it:

User Identification: Users are identified uniquely, usually by their username or user ID.

Shopping Cart: Each shopping cart contains products and quantities, which can be represented as another Map.

Structure: The outer Map links each user to their shopping cart, and the inner Map links each product to its quantity in the cart.

Example Code:

import java.util.HashMap;
import java.util.Map;

public class ShoppingCartManager {
// Map to associate each user with their shopping cart (which is another map of product to quantity)
private Map<String, Map<String, Integer>> userCarts;

public ShoppingCartManager() {
userCarts = new HashMap<>();
}

// Method to add a product to a user's cart
public void addProduct(String userId, String product, int quantity) {
// If the user doesn't have a cart yet, create one
userCarts.putIfAbsent(userId, new HashMap<>());

// Get the user's cart
Map<String, Integer> cart = userCarts.get(userId);

// Add or update the product quantity in the cart
cart.put(product, cart.getOrDefault(product, 0) + quantity);
}

// Method to view the cart contents
public Map<String, Integer> getCartContents(String userId) {
return userCarts.getOrDefault(userId, new HashMap<>());
}

// Example usage
public static void main(String[] args) {
ShoppingCartManager manager = new ShoppingCartManager();

// Adding products to user carts
manager.addProduct("Alice", "Laptop", 1);
manager.addProduct("Bob", "Smartphone", 2);
manager.addProduct("Alice", "Headphones", 3);

// Retrieving and displaying cart contents
System.out.println("Alice's Shopping Cart: " + manager.getCartContents("Alice"));
System.out.println("Bob's Shopping Cart: " + manager.getCartContents("Bob"));
}
}

In the above example code,

UserCarts Map: userCarts is a HashMap where the key is a String (the user’s ID) and the value is another Map (the user’s shopping cart). The shopping cart Map has product names as keys and quantities as values.

addProduct Method: Adds products to a user’s cart. If the user does not have a cart, it creates one. It then adds the product to the cart, incrementing the quantity if the product is already in the cart.

getCartContents Method: Returns the contents of a user’s cart. If the user has no cart, it returns an empty cart.

Output:

Alice's Shopping Cart: {Headphones=3, Laptop=1}
Bob's Shopping Cart: {Smartphone=2}

Conclusion

The Map interface in Java provides a powerful way to store and manage data as key-value pairs. Understanding its workings and the differences between its implementations is essential for effectively organizing data in Java applications. Whether you need ordered data, fast access, or synchronized access, there’s a Map implementation that fits the need.

By mastering the Map interface and its various implementations, Java developers can efficiently handle complex data structures, leading to more robust and maintainable code.

Happy Learning !!!

--

--

Reetesh Kumar

Software developer. Writing about Java, Spring, Cloud and new technologies. LinkedIn: www.linkedin.com/in/reeteshkumar1