Introduction
Java 8 introduced lambda expressions and the Stream API, which brought new ways to process collections in a more concise and functional manner. Sorting a collection by multiple fields is a common requirement in many applications, such as sorting a list of objects first by one attribute (e.g., name) and then by another (e.g., price). Before Java 8, achieving this required writing complex comparator logic. With lambda expressions and the Comparator class enhancements, sorting by multiple fields has become much simpler.
In this blog post, we’ll explore how to use lambda expressions to sort a list of objects by multiple fields in Java 8.
Table of Contents
- Problem Statement
- Solution Steps
- Java Program
- Sorting by Multiple Fields Using Lambda Expressions
- Advanced Considerations
- Conclusion
Problem Statement
The task is to create a Java program that:
- Sorts a list of custom objects by multiple fields using lambda expressions.
- Demonstrates how to achieve primary and secondary sorting using the
Comparatorclass in Java 8.
Example:
- Input: A list of
Productobjects, each with attributes such asnameandprice. - Output: The list sorted first by name alphabetically and then by price in ascending order.
Solution Steps
- Create a
ProductClass: Define aProductclass with attributes such asid,name, andprice. - Create a List of
ProductObjects: Define a list ofProductobjects. - Use the
ComparatorClass: Utilize theComparator.comparing()method and lambda expressions to sort by multiple fields. - Chain Comparators: Use
thenComparing()to chain multiple comparators for sorting.
Java Program
Sorting by Multiple Fields Using Lambda Expressions
Below is an example that demonstrates how to sort a list of Product objects first by name and then by price.
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* Java 8 - How to Use Lambda Expressions to Sort by Multiple Fields
* Author: https://www.rameshfadatare.com/
*/
class Product {
private int id;
private String name;
private double price;
public Product(int id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
@Override
public String toString() {
return "Product{id=" + id + ", name='" + name + "', price=" + price + "}";
}
}
public class SortByMultipleFieldsExample {
public static void main(String[] args) {
// Step 1: Create a list of Product objects
List<Product> products = new ArrayList<>();
products.add(new Product(1, "Laptop", 1200.00));
products.add(new Product(2, "Smartphone", 800.00));
products.add(new Product(3, "Tablet", 300.00));
products.add(new Product(4, "Smartphone", 1200.00));
products.add(new Product(5, "Smartwatch", 150.00));
products.add(new Product(6, "Headphones", 150.00));
// Step 2: Sort the list by name and then by price using lambda expressions
products.sort(Comparator.comparing(Product::getName)
.thenComparing(Product::getPrice));
// Step 3: Display the sorted list
products.forEach(System.out::println);
}
}
Output
Product{id=6, name='Headphones', price=150.0}
Product{id=1, name='Laptop', price=1200.0}
Product{id=5, name='Smartwatch', price=150.0}
Product{id=2, name='Smartphone', price=800.0}
Product{id=4, name='Smartphone', price=1200.0}
Product{id=3, name='Tablet', price=300.0}
Explanation
- Product Class: The
Productclass defines the structure of a product withid,name, andpriceattributes. - Sorting by Multiple Fields: The
Comparator.comparing(Product::getName)creates a comparator that sorts the products by name. ThethenComparing(Product::getPrice)chains a second comparator that sorts by price for products with the same name. - Sorting Order: By default,
Comparator.comparing()sorts in ascending order. If you want to sort in descending order, you can useComparator.comparing(Product::getName).reversed()orComparator.comparing(Product::getPrice).reversed().
Advanced Considerations
-
Sorting by Multiple Fields with Custom Logic: You can use custom comparator logic in
thenComparing()if your sorting criteria are more complex:products.sort(Comparator.comparing(Product::getName) .thenComparing((p1, p2) -> Double.compare(p2.getPrice(), p1.getPrice()))); // Descending price -
Null Handling: If your list might contain
nullvalues, consider usingComparator.nullsFirst()orComparator.nullsLast():products.sort(Comparator.comparing(Product::getName, Comparator.nullsFirst(String::compareTo)) .thenComparing(Product::getPrice)); -
Combining Multiple Comparators: You can continue chaining as many
thenComparing()methods as necessary to sort by multiple fields.
Conclusion
This blog post demonstrated how to use lambda expressions to sort a list of objects by multiple fields in Java 8. By leveraging the Comparator.comparing() and thenComparing() methods, you can easily create complex sorting logic that is both concise and readable. Whether you’re sorting by two fields or more, these tools provide a powerful way to manage complex data sorting requirements in your Java applications.