Hello! In our last lesson, we explored how to use the Deque interface to implement stacks and queues, leveraging the power of Java's built-in collections. We saw how choosing the right data structure (ArrayDeque) can lead to clean and efficient code for problems like validating parentheses.
Today, we'll continue this theme by diving into one of the most versatile and frequently used data structures in all of programming: the HashMap. Our goal is to master its use for two common tasks: performing quick lookups and counting frequencies. Understanding HashMap is absolutely essential for a backend developer, as it forms the basis for caching, indexing, and processing data efficiently.
1. Understanding the HashMap: A Key-Value Store
At its core, a HashMap is a data structure that stores data in key-value pairs. For every unique key, you can store a corresponding value. The "magic" of a HashMap is its ability to find the value associated with a key extremely quickly, usually in constant time, regardless of how many pairs are stored.
This is analogous to a dictionary, where you look up a word (the key) to find its definition (the value). Given your experience with MongoDB, you can think of a simple HashMap as being similar in concept to a single JSON document or BSON object, where you have fields (keys) and their associated data (values).
Let's begin with a video that introduces the Map interface and its most common implementation, HashMap.
Map and HashMap in Java - Full Tutorial
This tutorial from the "Coding with John" channel provides a clear, practical introduction to HashMap in Java.
Please watch the following segments: First, watch the introduction from the basic concept of a map using an employee ID example. Next, see how a HashMap is declared in Java from creating a map. Pay close attention to the use of generics (<String, Integer>) to define the types for keys and values, and the distinction between the Map interface and the HashMap class. Finally, watch the important note on using wrapper classes from primitive types. This is a critical detail in Java collections.
As the video explained, Map is an interface that defines the contract for key-value mappings, and HashMap is the most common concrete implementation you will use.
2. Core Operations: The Foundation of Quick Lookups
The power of HashMap for "quick lookups" comes from its fundamental methods. These allow you to add, retrieve, check for, and remove data efficiently.
Let's continue with the same video to see these operations in action.
Map and HashMap in Java - Full Tutorial
This part of the tutorial demonstrates the essential methods for interacting with a HashMap.
Watch these clips to understand the core functionality: Adding Data: See how to add key-value pairs using the put() method here. Retrieving Data: Learn how to get a value for a given key using the get() method in this segment. Checking for Existence: Understand how to check if a map contains a specific key or value with containsKey() and containsValue() from this part. Removing Data: Finally, see how to remove a key-value pair using remove() here.
It's also important to understand how put() behaves when a key already exists—it simply overwrites the old value with the new one. The video also briefly touched on methods like replace() and putIfAbsent(), which give you more explicit control over this behavior.
The following image provides a great "cheat sheet" summarizing the most common HashMap operations, including many we've just discussed.

3. Application: Frequency Counting
Now that you understand the basics, let's apply them to a classic problem: frequency counting. Given a collection of items (like numbers in an array or characters in a string), we want to count how many times each unique item appears. This pattern is incredibly useful in data analysis, text processing, and many algorithm challenges.
The HashMap is perfect for this. We can use the item itself as the key and its frequency (count) as the value.
The general algorithm is as follows:
- Initialize an empty
HashMap. For counting numbers, this would beHashMap<Integer, Integer>. - Iterate through each element in the input array.
- For each element:
- If the element is already a key in the map, retrieve its current count, add 1, and update the value.
- If the element is not in the map, add it as a new key with a value of 1.
The following video provides a step-by-step walkthrough of implementing this logic in Java.
Find Count Of Each Element from Array | Java Interview Questions and Answers
This video from the channel CloudTech demonstrates how to solve the frequency counting problem from scratch.
Watch the core logic unfold in these segments: Problem introduction: Understand the goal with a sample array. Setup: See the creation of the method and the initialization of the HashMap. Core Logic: This is the most important part. Pay close attention to the for loop and the if-else block that uses containsKey() to decide whether to update an existing count or add a new entry. Printing Results: Learn how to iterate over the completed map using its entrySet() to display the results.
4. A More Elegant Solution: getOrDefault()
The if-else logic from the video works perfectly, but modern Java provides a more concise and readable way to achieve the same result using the getOrDefault() method.
The method map.getOrDefault(key, defaultValue) does exactly what its name implies: it tries to get the value for a given key. If the key is not found, it returns the defaultValue you provided instead of null.
This allows us to simplify the core logic of our frequency counting loop into a single, expressive line:
map.put(element, map.getOrDefault(element, 0) + 1);
Let's break this down:
map.getOrDefault(element, 0): This fetches the current count of theelement. If theelementisn't in the map yet, it returns0.... + 1: We add 1 to this count (either the existing one or0).map.put(element, ...): We thenputthe element back into the map with its new, incremented count.
This one-liner elegantly handles both cases (the key exists or it doesn't) without an explicit conditional block.
Introduction to HashMaps in Java for Counting Occurrences
This article from CodeSignal demonstrates and explains the getOrDefault optimization for frequency counting.
Start reading from the section Introducing HashMaps. First, review the initial solution that uses a conditional check. Then, focus on the section optimized solution that introduces and explains the getOrDefault method.
5. Time Complexity and Practical Examples
Why is HashMap so good for this? The answer lies in its performance. On average, the put(), get(), and containsKey() methods all operate in constant time, denoted as O(1). This means the time it takes to perform these operations doesn't increase as the map gets larger.
Because we iterate through our input array of size n once, and each operation inside the loop is O(1), the total time complexity for frequency counting with a HashMap is O(n). This is a highly efficient, linear-time solution.
Introduction to HashMaps in Java for Counting Occurrences
This same CodeSignal article provides an excellent, concise analysis of the time and space complexity.
Please read the section titled Time Complexity Analysis. This will solidify your understanding of why this approach is so performant.
This frequency counting pattern can be applied to many different scenarios. The following resource shows several practical code examples.
Java HashMap Programs And Coding Examples
This article from "Java Concept Of The Day" provides a variety of HashMap-based coding problems and their solutions.
Focus on the following questions in the article: Question 11: Find the frequency of each element in an array and each character in a string. This directly reinforces what we've just learned. Question 16: Given a sentence, count the occurrences of each word. This shows the same pattern applied to strings.
Conclusion
In this lesson, you've added the HashMap to your Java toolkit, a data structure that is fundamental to solving a wide range of problems efficiently. You now have a solid grasp of its purpose and practical application.
Key Takeaways:
- A
HashMapstores unique keys mapped to values, providing extremely fast O(1) average time complexity for lookups, insertions, and deletions. - It is the ideal tool for problems requiring quick lookups, such as checking for the existence of an item or retrieving data associated with an identifier.
- The frequency counting pattern is a common and powerful application of
HashMap, where items are keys and their counts are values. - Using the
getOrDefault()method provides a clean, modern, and concise way to implement frequency counting logic.
In our next lesson, we will shift gears slightly. We've spent the last few lessons learning to use powerful built-in Java collections. Next, we will return to implementing algorithms from first principles as we explore binary trees and how to traverse them using recursion. This will be another crucial step in strengthening your core DSA foundations.