In Java, working with Iterable types like lists are common, but sometimes we need to map a collection of objects (such as a list of entities) to a single non-iterable object (like a DTO or summary object). This is where MapStruct comes in. MapStruct is a Java annotation-based mapper that simplifies the process of converting between different types, including iterable to non-iterable transformations. Let us delve into understanding how to use Java MapStruct for mapping an Iterable to an object.
1. Understand the Use Case
Imagine you have a list of Product entities and you need to map it to a summary object, such as a ProductSummaryDTO, containing an aggregate of information from the list. The challenge here is converting the list (an iterable type) into a single object (a non-iterable type). Let’s take an example:
- We have a list of products with
priceandquantityfields. - We want to map it to a single object,
ProductSummaryDTO, which contains total price and total quantity.
2. Map Iterable to Non-Iterable Type
MapStruct doesn’t directly support converting iterables to single objects out of the box, but we can implement custom mapping methods to achieve this. By using MapStruct’s @Mapper annotation and custom mapping logic, we can transform iterables into objects.
2.1 Solution
Let’s go through the process step-by-step:
2.1.1 Create Product Entity
The class is a simple Java class (also known as POJO – Plain Old Java Objects) that models a product with two attributes – price and quantity.
public class Product {
private double price;
private int quantity;
// Constructors, Getters, and Setters
public Product(double price, int quantity) {
this.price = price;
this.quantity = quantity;
}
public double getPrice() {
return price;
}
public int getQuantity() {
return quantity;
}
}
2.1.2 Create ProductSummaryDTO
The ProductSummaryDTO class is a DTO class that represents a summary of multiple products. It contains two key pieces of information:
- totalPrice: The total price of all products.
- totalQuantity: The total quantity of products.
This class is commonly used when we need to represent an aggregate view of product data (such as the combined price and quantity of a list of products).
public class ProductSummaryDTO {
private double totalPrice;
private int totalQuantity;
// Constructors, Getters, and Setters
public ProductSummaryDTO(double totalPrice, int totalQuantity) {
this.totalPrice = totalPrice;
this.totalQuantity = totalQuantity;
}
public double getTotalPrice() {
return totalPrice;
}
public int getTotalQuantity() {
return totalQuantity;
}
}
2.1.3 Custom Mapping Logic using MapStruct
We will use MapStruct to write a custom mapper method that will take a list of Product objects and map them to ProductSummaryDTO.
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface ProductMapper {
ProductMapper INSTANCE = Mappers.getMapper(ProductMapper.class);
default ProductSummaryDTO mapToProductSummary(Iterable<Product> products) {
double totalPrice = 0;
int totalQuantity = 0;
for (Product product : products) {
totalPrice += product.getPrice();
totalQuantity += product.getQuantity();
}
return new ProductSummaryDTO(totalPrice, totalQuantity);
}
}
The code defines a:
@Mapper: This is the MapStruct annotation that marks the interface as a mapper.mapToProductSummary: This is the custom mapping method that iterates through theIterable<Product>and aggregates the total price and quantity.- Inside the method, we loop through each product, sum the prices and quantities, and return a new
ProductSummaryDTOwith the results.
2.1.4 Code Output
Now let’s test the mapper:
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Product> productList = Arrays.asList(
new Product(10.5, 2),
new Product(20.0, 3),
new Product(5.5, 1)
);
ProductSummaryDTO summary = ProductMapper.INSTANCE.mapToProductSummary(productList);
System.out.println("Total Price: " + summary.getTotalPrice());
System.out.println("Total Quantity: " + summary.getTotalQuantity());
}
}
When the code is executed the following output will be logged on the IDE console.
Total Price: 36.0 Total Quantity: 6
3. Conclusion
In this article, we demonstrated how to use MapStruct to map an Iterable (a list of products) to a single object (a summary DTO). While MapStruct doesn’t natively support this out-of-the-box, by writing custom mapping methods, we can easily handle complex mappings. This solution is particularly useful for scenarios where we need to aggregate data from collections into a single object. MapStruct’s flexibility and ease of use make it a powerful tool for transforming data between different types in a clean, maintainable way.
Thank you!
We will contact you soon.
Yatin BatraOctober 16th, 2024Last Updated: October 15th, 2024

This site uses Akismet to reduce spam. Learn how your comment data is processed.