21
NovHashMap in Java: A Detailed Explanation
HashMap in Java
HashMap in Java has been a crucial part of Java's collection framework since version 1.2, which can be found in the java.util.package. It offers a simple implementation of Java's Map interface. In Java, HashMap holds data in (Key, Value) pairs that may be accessed using an index of another type (for example, an integer). One item serves as a key (index) to another (value). If you try to enter a duplicate key into HashMap, it will replace the element for the associated key.
In this Java tutorial, we will learn about HashMap in Java, including its hierarchy, creating a HashMap, Java HashMap Constructors, adding and accessing elements, iterating over a HashMap, HashMap vs. TreeMap vs. LinkedHashMap, and many more.
Take your career to the next level by joining our comprehensive Java Full Stack Developer Certification Training today!
What is HashMap in Java?
HashMap in Java is a data structure that is part of the Java Collections Framework and is used for storing key-value pairs, where each key is unique. It is similar to the hash table, but it is not synchronized. It allows us to store null elements as well, but there should be only one null key object, and there can be any number of null values. Let's dive into some important points about HashMap:
- Save data in key-value pairs, where each key is unique.
- To allow efficient access, a hashing technique is used, with get() and put() operations often taking O(1) time.
- Does not assure the order of elements, as the order can change over time.
- Allow one null key and multiple null values.
- It is not thread-safe and requires external synchronization for concurrent access.
- Dynamically increases its size when the number of elements exceeds a certain threshold to maintain performance.
- Manages hash collisions using linked lists or binary trees within the buckets.
Read More |
Java Full Stack Development Roadmap |
OOPs Concepts in Java: Encapsulation, Abstraction, Inheritance, Polymorphism |
Hierarchy of HashMap in Java
Creating and Using HashMap in Java
Creating and using a HashMap in Java involves instantiating the map with specified key-value types and then performing operations like adding, retrieving, and removing entries. This allows for efficient data management and quick access based on unique keys.
1. Creating a HashMap
To create a HashMap, we first have to import the java.util.HashMap package. After we import the package, we can create a HashMap in Java.
Syntax
// creating a HashMap
HashMap<KeyType, ValueType> mapName = new HashMap<>();
2. Adding Elements in Hashmap
To add the elements in HashMap in Java, we should use the put() method. The syntax for adding elements in Hashmap is given below;
Syntax
HashMap<KeyType, ValueType> mapName = new HashMap<>();
//Adding elements in the HashMap
map.put(key, value);
Example
Let's understand an example of how to create and add elements in the HashMap;
import java.util.HashMap;
class Main {
public static void main(String[] args) {
// create a hashmap
HashMap languages = new HashMap<>();
// add elements to hashmap
languages.put("Java", 8);
languages.put("JavaScript", 1);
languages.put("Python", 3);
System.out.println("HashMap: " + languages);
}
}
Output
HashMap: {Java=8, JavaScript=1, Python=3}
Java HashMap Constructors
- HashMap()
- HashMap(int initialCapacity)
- HashMap(int initialCapacity, float load factor)
- HashMap(Map map)
1. HashMap()
It is also called the default constructor, which initializes a HashMap with a starting capacity of 16 and a load factor of 0.75.Syntax
HashMap<KeyTalue, ValueType> mapName = new HashMap();
Example
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// Create a new HashMap using the default constructor
HashMap<String, Integer> map = new HashMap<>();
// Add some key-value pairs to the HashMap
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Cherry", 3);
// Print the HashMap
System.out.println(map);
}
}
Output
{Apple=1, Banana=2, Cherry=3}
2. HashMap(int initialCapacity)
The HashMap(int initialCapacity) constructor generates a HashMap with a given initial capacity and 0.75 load factor. This implies that the HashMap will begin with a set number of buckets, which might assist in improving efficiency if you know roughly how many items will be stored.Syntax
HashMap<KeyType, ValueType> mapName = new HashMap<>(int initialCapacity);
Example
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// Create a HashMap with an initial capacity of 20
HashMap<String, Integer> map = new HashMap<>(20);
// Add some key-value pairs to the HashMap
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Cherry", 3);
map.put("Date", 4);
// Print the HashMap
System.out.println(map);
}
}
Output
{Apple=1, Banana=2, Cherry=3, Date=4}
3. HashMap(int initialCapacity, float load factor)
The HashMap (int initialCapacity, float load factor) constructor in Java creates a HashMap with a specified initial capacity and load factor. This allows you to set both the HashMap's beginning size and its sensitivity to how full it is before resizing.Syntax
HashMap<KeyType, ValueType> map = new HashMap<>(int initialCapacity, float loadFactor);
Example
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// Create a HashMap with an initial capacity of 10 and a load factor of 0.5
HashMap<String, Integer> map = new HashMap<>(10, 0.5f);
// Add some key-value pairs to the HashMap
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Cherry", 3);
map.put("Date", 4);
// Print the HashMap
System.out.println(map);
}
}
Output
{Apple=1, Banana=2, Cherry=3, Date=4}
4. HashMap(Map map)
Syntax
HashMap<KeyType, ValueType> map = new HashMap<>(Map<? extends KeyType, ? extends ValueType> m);
Example
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Create an existing map with some entries
Map<String, Integer> originalMap = new HashMap<>();
originalMap.put("Apple", 1);
originalMap.put("Banana", 2);
originalMap.put("Cherry", 3);
// Create a new HashMap by copying the entries from the original map
HashMap<String, Integer> copiedMap = new HashMap<>(originalMap);
// Print the copied HashMap
System.out.println(copiedMap);
}
}
Output
{Apple=1, Banana=2, Cherry=3}
Read More |
Constructor Chaining in Java |
for Loop in Java: Its Types and Examples |
do...while Loop in Java - Flowchart & Syntax |
Some Operations on HashMap
There are various types of operations are performed on HashMap, but we will look into some basic operations that are mostly performed in Hashmap:- Adding Elements in HashMap
- Change Elements in HashMap
- Remove Elements in HashMap
- Iterating over a HashMap
1. Adding and Accessing Elements in HashMap
The HashMap(int initialCapacity) constructor generates a HashMap with a given initial capacity and 0.75 load factor. This implies that the HashMap will begin with a set number of buckets, which might assist in improving efficiency if you know roughly how many items will be stored.Example
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// Creating a HashMap
HashMap<String, Integer> map = new HashMap<>();
// Adding elements to the HashMap
map.put("Apple", 10);
map.put("Banana", 20);
map.put("Orange", 30);
System.out.println(map);
// Accessing elements in the HashMap
String key = "Banana";
Integer value = map.get(key);
// Checking if the key exists in the HashMap
if (value != null) {
System.out.println("Value for key \"" + key + "\" is: " + value);
} else {
System.out.println("Key \"" + key + "\" not found in the HashMap.");
}
}
}
Output
{Apple=10, Orange=30, Banana=20}
Value for key "Banana" is: 20
Note:We can also access the keys, values, and key/value pairs of the hashmap as set views using keySet(), values(), and entrySet() methods, respectively. |
Example
import java.util.HashMap;
class Main {
public static void main(String[] args) {
HashMap<Integer, String> languages = new HashMap<>();
languages.put(1, "Java");
languages.put(2, "Python");
languages.put(3, "JavaScript");
System.out.println("HashMap: " + languages);
// return set view of keys
// using keySet()
System.out.println("Keys: " + languages.keySet());
// return set view of values
// using values()
System.out.println("Values: " + languages.values());
// return set view of key/value pairs
// using entrySet()
System.out.println("Key/Value mappings: " + languages.entrySet());
}
}
Output
HashMap: {1=Java, 2=Python, 3=JavaScript}
Keys: [1, 2, 3]
Values: [Java, Python, JavaScript]
Key/Value mappings: [1=Java, 2=Python, 3=JavaScript]
2. Change Elements in HashMap
To modify an element in a HasMap in Java, use the put() function. If the key already exists in the HashMap, the put() function updates the value associated with it. If the key is not there, a new key-value pair will be created.Example
import java.util.HashMap;
public class FruitInventory {
public static void main(String[] args) {
// Create a HashMap to store fruit quantities
HashMap<String, Integer> fruitQuantities = new HashMap<>();
// Add some fruits and their quantities to the HashMap
fruitQuantities.put("Apple", 10);
fruitQuantities.put("Banana", 20);
fruitQuantities.put("Orange", 15);
// Print the original HashMap
System.out.println("Original fruit quantities: " + fruitQuantities);
// Update the quantity of Apples
fruitQuantities.put("Apple", 25);
// Print the updated HashMap
System.out.println("Updated fruit quantities: " + fruitQuantities);
}
}
Output
Original fruit quantities: {Apple=10, Banana=20, Orange=15}
Updated fruit quantities: {Apple=25, Banana=20, Orange=15}
3. Remove Element in HashMap
Example
import java.util.HashMap;
public class RemoveElement {
public static void main(String[] args) {
// Create a HashMap to store some fruit quantities
HashMap fruitQuantities = new HashMap<>();
// Add some fruits and their quantities to the HashMap
fruitQuantities.put("Apple", 10);
fruitQuantities.put("Banana", 20);
fruitQuantities.put("Orange", 15);
// Print the original HashMap
System.out.println("Original fruit quantities: " + fruitQuantities);
// Remove "Banana" from the HashMap
fruitQuantities.remove("Banana");
// Print the updated HashMap
System.out.println("Updated fruit quantities after removing Banana: " + fruitQuantities);
}
}
Output
Original fruit quantities: {Apple=10, Banana=20, Orange=15}
Updated fruit quantities after removing Banana: {Apple=10, Orange=15}
4. Iterating over a Hashmap
Iterating over a HashMap means going through each key-value pair stored in the HashMap and performing operations on them, such as reading their contents, altering them, or utilizing them in some logic. We utilize Java for each loop to iterate over keys only, values only, and key/value mapping.Example
import java.util.HashMap;
import java.util.Map.Entry;
class Main {
public static void main(String[] args) {
// create a HashMap
HashMap<Integer, String> languages = new HashMap<>();
languages.put(1, "Java");
languages.put(2, "Python");
languages.put(3, "JavaScript");
System.out.println("HashMap: " + languages);
// iterate through keys only
System.out.print("Keys: ");
for (Integer key : languages.keySet()) {
System.out.print(key);
System.out.print(", ");
}
// iterate through values only
System.out.print("\nValues: ");
for (String value : languages.values()) {
System.out.print(value);
System.out.print(", ");
}
// iterate through key/value entries
System.out.print("\nEntries: ");
for (Entry entry : languages.entrySet()) {
System.out.print(entry);
System.out.print(", ");
}
}
}
Output
HashMap: {1=Java, 2=Python, 3=JavaScript}
Keys: 1, 2, 3,
Values: Java, Python, JavaScript,
Entries: 1=Java, 2=Python, 3=JavaScript,
The Internal structure of HashMap
- As seen in the node form above, a node is structured similarly to a linked list node. A bucket refers to an array of these nodes. HashMap holds elements in buckets, the number of which is referred to as capacity.
- When we add a value to the map, the key's hashCode() function determines which bucket it will be kept in. Essentially, a hash value is calculated using the key's hash code. This hash value is used to compute the index in the array where the Entry object will be stored.
- When we try to get the item, the HashMap creates the bucket in the same way: by using hashCode(), which calculates the initial index position. Then, in that bucket, it iterates through the discovered objects, using the key's equals() function to locate an exact match.
- To avoid having a large number of buckets with various values, the capacity is increased if 75% (the load factor) of the buckets are not empty. The baseline load factor is 75%, and the starting capacity is 16. Both may be set in the constructor, as previously described.
Performance of HashMap
The performance of Hashmap depends on 4 factors that are explained below:
- Initial Capacity
- Load Factor
- Threshold
- Rehashing
1. Initial Capacity
It refers to the capacity of a HashMap at the moment of formation. In Java, the initial value is 2^4=16, indicating that it can retain 16 key-value pairs.
2. Load factor
It is the percentage value of the capacity, after which the Hashmap capacity will be enhanced. In Java, it is set to 0.75f by default, which means that rehashing occurs once 75% of the capacity is filled.
3. Threshold
It is the product of the load factor and the initial capacity. In Java, the default is (16 * 0.75 = 12). That is, Rehashing occurs after entering 12 key-value pairs into the HashMap.
4. Rehasing
It is the process of doubling the capacity of a HashMap after it has reached its Threshold. In Java, HashMap rehashes (by default) in the following sequence: 2^4, 2^5, 2^6, 2^7, and so on.
Advanced Features and Best Practices
Features of HashMap
Here are the advanced features of HashMap in Java:
- Stores data in key-value pairs for efficient retrieval by key.
- Utilizes a hash function to provide average O(1) time complexity for operations.
- Manages collisions using linked lists or trees within buckets.
- Automatically resizes and rehashes when the load factor threshold is exceeded.
- Support one null key and multiple null values with unordered iterations.
Comparing HashMap - HashMap vs. TreeMap vs. LinkedHashMap
Features | HashMap | TreeMap | LinkedHashMap |
Order | No specific order | Sorted by key | Insertion or access order |
Implementation | Hash table | Red-Black Tree | Hash table + linked list |
Time Complexity | O(1) average, O(n) worst | O(log n) | O(1) average |
Null Keys/Values | One null key, multiple null values | No null keys, multiple null values | One null key, multiple null values |
Use Case | Fast lookups, unordered data | Sorted keys, range queries | Predictable iteration order |
Real-World Applications and Use Cases of HashMap
HashMap is a versatile data structure with a range of real-world applications and use cases due to its efficiency and flexibility. Here are some common scenarios where HashMap is particularly useful:
1. Caching Data
Storing frequently accessed data to improve performance by reducing repeated computations or database queries.
2. Counting Occurrences
Counting word frequencies in a text file or counting occurrences of specific events in logs.
3. Lookup Tables
Creating fast lookup tables for quick access to data based on unique keys.
4. Implementing Indexes
Building indexes for databases or data structures to provide quick access to records based on certain keys.
5. Graph Representations
Representing graphs where nodes can be mapped to adjacency lists or other structures.
6. Job Scheduling
Managing job queues or scheduling tasks based on unique identifiers.
Conclusion
FAQs
- HashMap stores key-value pairs allows unique keys with duplicate values and is used for data retrieval based on keys.
- HashSet stores unique elements does not allow duplicates and is used when you need a collection of unique items.