This content originally appeared on Level Up Coding - Medium and was authored by Ivan Polovyi
The Map interface contains an intriguing and powerful method called merge. While incredibly useful, it can initially appear confusing. In this tutorial, I will walk you through the merge method, explaining its functionality and demonstrating with examples how it works and what it can be used for. By the end, you'll see just how valuable and versatile this method can be in your Java programming toolkit.
Introduction
The merge method of the Map interface is a default method that has the following signature:
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {...}
This method accepts three parameters: a key, a value, and a BiFunction. The method returns a value mapped to a given key. The flow of this method can be illustrated with the following diagram:
Now, let's check each flow separately.
Flow #1
The first flow is quite straightforward. If the key specified as the first parameter is not present in the Map, it is added with the value provided as the second parameter.
Check the example below:
private static void addNewValue() {
System.out.println("AddNewValue:");
Map<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
System.out.println("map before = " + map);
// map before = {1=A, 2=B}
String returnedValue = map.merge(3, "C",
(value, newValue) -> "Some value");
System.out.println("returnedValue = " + returnedValue);
// returnedValue = C
System.out.println("map after = " + map);
// map after = {1=A, 2=B, 3=C}
}
Flow #2
The second flow occurs when the key is present in the Map. In this case, the BiFunction is executed. If the result of the BiFunction execution is null, the entry with the specified key is removed from the Map.
We can verify it with the following example:
private static void removeValue() {
System.out.println("RemoveValue:");
Map<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
System.out.println("map before = " + map);
// map before = {1=A, 2=B}
String returnedValue = map.merge(2, "New Value",
(value, newValue) -> null);
System.out.println("returnedValue = " + returnedValue);
// returnedValue = null
System.out.println("map after = " + map);
// map after = {1=A}
}
Flow #3
The third flow is similar to the previous one, but with a key difference: when the BiFunction yields a result, the entry is added to the Map with the key specified as the first parameter and the value being the result of the BiFunction.
The code snipped below illustrates this case:
private static void calculateValueValue() {
System.out.println("CalculateValue:");
Map<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
System.out.println("map before = " + map);
// map before = {1=A, 2=B}
String returnedValue = map.merge(2, "New Value",
(value, newValue) -> value + "+" + newValue);
System.out.println("returnedValue = " + returnedValue);
// returnedValue = B+New Value
System.out.println("map after = " + map);
// map after = {1=A, 2=B+New Value}
}
Usage
Let’s consider a simple use case to demonstrate the usage. Imagine a company with a reward program where each customer accumulates points. This reward system can be represented using a map where the key is the customer ID, and the value is the number of points.
Map<String, Integer> rewardPoints = new TreeMap<>();
rewardPoints.put("Customer1", 100);
rewardPoints.put("Customer2", 200);
rewardPoints.put("Customer3", null); // customer left reward program
Let’s say we have a rule in place where the customer who earns the most rewards in a given period will double their points. We can implement this as follows:
// Customer2 earned bonus because he got the largest number of points
Integer rewardPointsWithBonus = rewardPoints.merge("Customer2", 2,
(oldValue, newValue) -> oldValue * newValue);
When we need to add a new customer to the program, we can do it like this:
// Add a new customer to a reward program
Integer newCustomerValue = rewardPoints.merge("Customer4", 0,
(oldValue, newValue) -> oldValue + newValue);
In a case where a particular customer earned points but has already left the program, adding their points will result in their removal because their points are null.
// Remove customer from reward program, although he earned some points in the last month
Integer inactiveCustomer = rewardPoints.merge("Customer3", 100,
(oldValue, newValue) -> oldValue + newValue);
If we need to sum up rewards from another program, such as a cashback program, located in a different map, we will loop over the map and merge it with the existing one like this:
Map<String, Integer> cashBackPoints = new TreeMap<>();
cashBackPoints.put("Customer1", 150);
cashBackPoints.put("Customer2", 75);
cashBackPoints.put("Customer4", 300);
cashBackPoints.forEach((item, qty) -> rewardPoints.merge(item, qty,
(oldValue, newValue) -> oldValue + newValue));
The complete class is here:
package com.polovyi.ivan.tutorials;
import java.util.Map;
import java.util.TreeMap;
public class Example {
public static void main(String[] args) {
Map<String, Integer> rewardPoints = new TreeMap<>();
rewardPoints.put("Customer1", 100);
rewardPoints.put("Customer2", 200);
rewardPoints.put("Customer3", null); // customer left reward program
System.out.println("initial reward points = " + rewardPoints);
// {Customer1=100, Customer2=200, Customer3=null}
// Customer1 got bonus because he got the largest number of points
Integer rewardPointsWithBonus = rewardPoints.merge("Customer2", 2, (oldValue, newValue) -> oldValue * newValue);
System.out.println("rewardPointsWithBonus = " + rewardPointsWithBonus);
// rewardPointsWithBonus = 400
System.out.println("reward points after bonus= " + rewardPoints);
// {Customer1=100, Customer2=400, Customer3=null}
// Add a new customer to a reward program
Integer newCustomerValue = rewardPoints.merge("Customer4", 0, (oldValue, newValue) -> oldValue + newValue);
System.out.println("newCustomerValue = " + newCustomerValue);
// newCustomerValue = 100
System.out.println("reward points after adding new customer = " + rewardPoints);
// {Customer1=100, Customer2=400, Customer3=null, Customer4=0}
// Remove customer from reward program, although he earned some points in the last month
Integer inactiveCustomer = rewardPoints.merge("Customer3", 100, (oldValue, newValue) -> oldValue + newValue);
System.out.println("inactiveCustomer = " + inactiveCustomer);
// inactiveCustomer = 100
System.out.println("reward points after removing customer = " + rewardPoints);
// {Customer1=100, Customer2=400, Customer3=100, Customer4=0}
Map<String, Integer> cashBackPoints = new TreeMap<>();
cashBackPoints.put("Customer1", 150);
cashBackPoints.put("Customer2", 75);
cashBackPoints.put("Customer4", 300);
cashBackPoints.forEach((item, qty) -> rewardPoints.merge(item, qty,
(oldValue, newValue) -> oldValue + newValue));
System.out.println("Total reward points after merging cashback points = " + rewardPoints);
// {Customer1=250, Customer2=475, Customer3=100, Customer4=300}
}
}
The complete code can be found here:
GitHub - polovyivan/java-collections-map-merge-method
Conclusion
In this tutorial, I provided a detailed explanation of how the merge method works. It is a versatile method that can perform many operations on a map. Some developers may avoid using it because it appears confusing at first. I hope that after this tutorial, you will use it in your day-to-day coding without any second thoughts.
Thank you for reading! If you enjoyed this post, please like and follow it. If you have any questions or suggestions, feel free to leave a comment or connect with me on my LinkedIn account.
Mastering Java Collections: Exploring merge Method in Maps was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Ivan Polovyi
Ivan Polovyi | Sciencx (2024-07-25T00:24:13+00:00) Mastering Java Collections: Exploring merge Method in Maps. Retrieved from https://www.scien.cx/2024/07/25/mastering-java-collections-exploring-merge-method-in-maps/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.