Stream API was intodruced in Java 8. It is a sequence of elements that supports different operations, such as filtering, sorting, mapping, and collecting from a collection. With its concise and readable syntax, lazy evaluation, and improved error handling, it has become an integral part of Java programming. Hence, it offers a powerful way to process collections, arrays, and other data sources.
This blog will discuss converting the Stream API into Map in Java. We have discussed two methods and provided examples to help you understand better.
Continue reading to check out!
Convert Maps Into Streams Using toMap() function
The method allows developers to create a new Map from a Stream. It takes two parameters as input: KeyMapper and ValueMapper. While the former function extracts map keys from stream values, the latter extracts the map values for the given key.
Here are some examples to teach how to implement the toMap Function, which converts the given stream into a map.
Example 1 covers a simple program for converting a Stream into a Map, while Example 2 covers a slightly more complex map conversion program.
Example 1
// Program to convert Stream into Map.
import java.io.*;
import java.util.stream.*;
import java.util.Arrays;
import java.util.Map;
class GFG {
//Function to convert the string to Map.
public static Map toMap(String input)
{
Map<String, Integer> lengthMap
= Arrays.stream(input.split(" "))
.collect(Collectors.toMap(
value
-> value,
value -> value.length()));
return lengthMap;
}
public static void main(String[] args)
{
String input = "Geeks for Geek";
System.out.println(toMap(input));
}
}
Output: {Geek=4, for=3, Geeks=5}
Explanation: Here, the keys are the words of the string, and the value is the length of each word. The toMap collector takes two parameters:
- (value -> value): Read the current stream value and return it as the map key.
- (value -> value.length): Reading the current stream value. It finds its length and returns the length value to the Map for the given key.
Example 2
// Program to convert User[] into Map<userId, User>
import java.util.Arrays;
import java.util.Map;
import java.util.stream.*;
// Implementing the User class
public class User {
// Attributes of the user class
private int userId;
private String name;
private String city;
// Constructor
public User(int userId, String name, String city)
{
this.userId = userId;
this.name = name;
this.city = city;
}
public int getUserId(){return userId;}
public String getName(){return name;}
public String getCity(){return city;}
// Overriding the toString method
// to return the custom string
@Override
public String toString()
{
return "User [userId = "
+ userId + ", name = "
+ name + ", city = "
+ city + "]";
}
}
class GFG {
//Function to convert the User to the Map
public static Map toMap(User user1, User user2,
User user3)
{
Map<Integer, User> userMap
= Arrays.asList(user1, user2, user3)
.stream()
.collect(Collectors.toMap(
user
-> user.getUserId(),
user -> user));
return userMap;
}
// Driver code
public static void main(String[] args)
{
// Creating users
User user1
= new User(1, "User1", "Srinagar");
User user2
= new User(2, "User2", "Kashmir");
User user3
= new User(3, "User3", "Jammu");
System.out.println(toMap(user1, user2,
user3));
}
}
Output: {1=User [userId = 1, name = User1, city = Srinagar], 2=User [userId = 2, name = User2, city = Kashmir], 3=User [userId = 3, name = User3, city = Jammu]}
Explanation: In this example, a list of users is converted into a map. Here, UserId is the key, and the User is the value.
Convert Map Into Stream Using Collectors Function
A groupingBy collector is a method by which collectors group objects by some property and convert them into a map. The groupingBy takes Function as input. It then creates a group of stream objects using that Function.
Here are some examples to teach how you can implement groupingBy collector function to convert the given stream into a map.
Example1
// Converts the User[] into Map<city, List<User>>
import java.util.Arrays;
import java.util.Map;
import java.util.List;
import java.util.stream.*;
// Implementing the User class
public class User {
// Parameters of the user class
private int userId;
private String name;
private String city;
// Constructor of the User class
public User(int userId, String name,
String city)
{
this.userId = userId;
this.name = name;
this.city = city;
}
public int getUserId(){return userId;}
public String getName(){ return name;}
public String getCity(){return city;}
// Overriding the toString() method
// to create a custom function
@Override
public String toString()
{
return "User [userId = "
+ userId + ", name = "
+ name + ", city = "
+ city + "]";
}
}
class GFG {
//Function to convert the user
// object to the Map
public static Map toMap(User user1,
User user2,
User user3,
User user4,
User user5)
{
Map<String, List<User> >
cityUserListMap
= Arrays.asList(user1, user2, user3,
user4, user5)
.stream()
.collect(Collectors.groupingBy(
User::getCity));
return cityUserListMap;
}
// Driver code
public static void main(String[] args)
{
// Creating new users
User user1
= new User(1, "User1", "Srinagar");
User user2
= new User(2, "User2", "Kashmir");
User user3
= new User(3, "User3", "Jammu");
User user4
= new User(4, "User4", "Srinagar");
User user5
= new User(5, "User5", "Kashmir");
System.out.println(toMap(user1, user2,
user3, user4,
user5));
}
}
Output: {Jammu=[User [userId = 3, name = User3, city = Jammu]], Srinagar=[User [userId = 1, name = User1, city = Srinagar], User [userId = 4, name = User4, city = Srinagar]], Kashmir=[User [userId = 2, name = User2, city = Kashmir], User [userId = 5, name = User5, city = Kashmir]]}
Explanation: Here, we have used the Function to convert a user stream into a map whose key is the city and the value of the users living there.
Example 2:
// Converts User[] into Map<city, countOfUser>
import java.util.Arrays;
import java.util.Map;
import java.util.stream.*;
// Implementing the user class
public class User {
// Parameters of the user class
private int userId;
private String name;
private String city;
// Constructor
public User(int userId, String name,
String city)
{
this.userId = userId;
this.name = name;
this.city = city;
}
public int getUserId(){return userId;}
public String getName(){return name;}
public String getCity(){return city;}
// Overriding the toString() method
// to create a custom function
@Override
public String toString()
{
return "User [userId = "
+ userId + ", name = "
+ name + ", city = "
+ city + "]";
}
}
class GFG {
public static Map toMap(User user1,
User user2,
User user3,
User user4,
User user5)
{
Map<String, Long>
cityUserCountMap
= Arrays.asList(user1, user2, user3,
user4, user5)
.stream()
.collect(
Collectors.groupingBy(
User::getCity,
Collectors.counting()));
return cityUserCountMap;
}
// Driver code
public static void main(String[] args)
{
// Creating new users
User user1
= new User(1, "User1", "Srinagar");
User user2
= new User(2, "User2", "Kashmir");
User user3
= new User(3, "User3", "Jammu");
User user4
= new User(4, "User4", "Srinagar");
User user5
= new User(5, "User5", "Kashmir");
System.out.println(toMap(user1, user2,
user3, user4,
user5));
}
}
Output: {Jammu=1, Srinagar=2, Kashmir=2}
Explanation: In this example, we have provided an additional collector to the groupingBy if we need more information than the actual object. Here, we get the count of the users belonging to each city.
Summary
The above blog has discussed efficient ways to convert data streams into maps to suit your specific needs. By leveraging these techniques in Java, you can efficiently manage data structures. It opens up new possibilities for developers to streamline their coding process.