Java Maps

Arshika Singh
5 min readJun 11, 2024

--

Introduction to Java Maps

In the Java programming language, a Map is a part of the Collections Framework that allows you to store key-value pairs. Unlike other collection types like List or Set which store individual elements, a Map stores mappings from keys to values. Each key in a map is unique, meaning no two keys can map to the same value. This structure is incredibly useful for situations where you need to associate data logically such as storing user IDs and their corresponding details or maintaining a directory of phone numbers.

Key Characteristics of Java Maps

Before diving into the specifics of different map implementations, let us understand some fundamental characteristics of Java Maps:

  1. Key-Value Pairs: Maps store data in pairs, with each key mapping to a specific value.
  2. Uniqueness of Keys: Keys in a map are unique, meaning no duplicate keys are allowed.
  3. Null Values and Keys: Maps may allow one null key and multiple null values depending on the implementation.
  4. No Order Guarantees: The order of elements in a map depends on the specific implementation.

The Map Interface

The Map interface in Java defines a collection of key-value pairs. It provides methods for basic operations such as adding, removing and retrieving elements.

Here are some of the primary methods in the Map interface:

  • put(K key, V value): Associates the specified value with the specified key in the map.
  • get(Object key): Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
  • remove(Object key): Removes the mapping for a key from this map if it is present.
  • 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.
  • keySet(): Returns a Set view of the keys contained in this map.
  • values(): Returns a Collection view of the values contained in this map.
  • entrySet(): Returns a Set view of the mappings contained in this map.
  • size(): Returns the number of key-value mappings in this map.
  • isEmpty(): Returns true if this map contains no key-value mappings.

Common Implementations of the Map Interface

Java provides several classes that implement the Map interface, each with its characteristics and use cases. The most commonly used implementations are HashMap, TreeMap and LinkedHashMap.

HashMap

HashMap is the most frequently used implementation of the Map interface. It is a hash table-based implementation that allows for constant-time performance for the basic operations (get and put), assuming the hash function disperses the elements properly among the buckets.

Characteristics

  • Ordering: HashMap does not guarantee any specific order of its elements.
  • Null Values and Keys: Allows one null key and multiple null values.
  • Performance: Provides constant-time performance for basic operations.

Example

Code:

import java.util.HashMap;

import java.util.Map;

public class HashMapExample {

public static void main(String[] args) {

Map<String, Integer> map = new HashMap<>();

map.put(“Apple”, 10);

map.put(“Banana”, 20);

map.put(“Orange”, 30);

int appleCount = map.get(“Apple”);

System.out.println(“Apple count: “ + appleCount);

System.out.println(“Map size: “ + map.size());

for (Map.Entry<String, Integer> entry : map.entrySet()) {

System.out.println(entry.getKey() + “ => “ + entry.getValue());

}

}

}

TreeMap

TreeMap is a Red-Black tree-based implementation of the Map interface. This implementation sorts the keys according to their natural order or by a specified comparator.

Characteristics

  • Ordering: TreeMap maintains a sorted order of its keys.
  • Null Values and Keys: It does not allow null keys but allows multiple null values.
  • Performance: Provides log(n) time cost for the basic operations (get, put, remove).

Example

Code:

import java.util.Map;

import java.util.TreeMap;

public class TreeMapExample {

public static void main(String[] args) {

Map<String, Integer> map = new TreeMap<>();

map.put(“Apple”, 10);

map.put(“Banana”, 20);

map.put(“Orange”, 30);

System.out.println(“Map size: “ + map.size());

for (Map.Entry<String, Integer> entry : map.entrySet()) {

System.out.println(entry.getKey() + “ => “ + entry.getValue());

}

}

}

LinkedHashMap

LinkedHashMap is a hash table and linked list implementation of the Map interface, with predictable iteration order. It maintains a doubly-linked list running through all of its entries which defines the iteration ordering.

Characteristics

  • Ordering: Maintains the insertion order of elements or the order in which keys were last accessed.
  • Null Values and Keys: Allows one null key and multiple null values.
  • Performance: Slightly slower than HashMap due to the maintenance of the linked list, but provides predictable iteration order.

Example

Code:

import java.util.LinkedHashMap;

import java.util.Map;

public class LinkedHashMapExample {

public static void main(String[] args) {

Map<String, Integer> map = new LinkedHashMap<>();

map.put(“Apple”, 10);

map.put(“Banana”, 20);

map.put(“Orange”, 30);

System.out.println(“Map size: “ + map.size());

for (Map.Entry<String, Integer> entry : map.entrySet()) {

System.out.println(entry.getKey() + “ => “ + entry.getValue());

}

}

}

Choosing the Right Map Implementation

When choosing which Map implementation to use, consider the following factors:

  1. Ordering: If you need the keys to be in a specific order, TreeMap or LinkedHashMap might be the best choice. Use TreeMap if you need the keys sorted and LinkedHashMap if you need to preserve the insertion order.
  2. Performance: For the best performance in most scenarios, HashMap is typically the way to go. It offers constant-time complexity for most operations.
  3. Memory Usage: If memory usage is a concern, HashMap generally has a smaller footprint than TreeMap.

Advanced Features

Customizing Key Comparison

In TreeMap, you can customize the order in which keys are compared by providing a custom Comparator when the map is created.

Code:

import java.util.Comparator;

import java.util.Map;

import java.util.TreeMap;

public class CustomComparatorExample {

public static void main(String[] args) {

Comparator<String> comparator = (a, b) -> b.compareTo(a); // Reverse order

Map<String, Integer> map = new TreeMap<>(comparator);

map.put(“Apple”, 10);

map.put(“Banana”, 20);

map.put(“Orange”, 30);

for (Map.Entry<String, Integer> entry : map.entrySet()) {

System.out.println(entry.getKey() + “ => “ + entry.getValue());

}

}

}

Synchronized Maps

If you need a thread-safe Map, you can use Collections.synchronizedMap to create a synchronized version of any Map implementation.

Code:

import java.util.Collections;

import java.util.HashMap;

import java.util.Map;

public class SynchronizedMapExample {

public static void main(String[] args) {

Map<String, Integer> map = new HashMap<>();

Map<String, Integer> synchronizedMap = Collections.synchronizedMap(map);

synchronizedMap.put(“Apple”, 10);

synchronizedMap.put(“Banana”, 20);

synchronizedMap.put(“Orange”, 30);

System.out.println(“Map size: “ + synchronizedMap.size());

synchronized (synchronizedMap) {

for (Map.Entry<String, Integer> entry : synchronizedMap.entrySet()) {

System.out.println(entry.getKey() + “ => “ + entry.getValue());

}

}

}

}

Concurrent Maps

For highly concurrent scenarios, consider using ConcurrentHashMap, which allows concurrent read and write operations without explicit synchronization.

Code:

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ConcurrentMap;

public class ConcurrentMapExample {

public static void main(String[] args) {

ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();

map.put(“Apple”, 10);

map.put(“Banana”, 20);

map.put(“Orange”, 30);

System.out.println(“Map size: “ + map.size());

for (Map.Entry<String, Integer> entry : map.entrySet()) {

System.out.println(entry.getKey() + “ => “ + entry.getValue());

}

}

}

Conclusion

The Map interface in Java is a powerful tool for managing key-value pairs. Understanding the different implementations — HashMap, TreeMap, LinkedHashMap and ConcurrentHashMap — and their respective characteristics is crucial for choosing the right one for your specific use case.

--

--

Arshika Singh

Techy| Web Designing | Search Engine Optimization | Digital Marketing | Logo Design