Java 8 – Sort a Stream of Objects

Introduction

Sorting a stream of objects is a common task in Java, especially when you need to order data for processing, display, or analysis. Java 8 introduced the Stream API, which provides a powerful and flexible way to sort collections of objects. Using lambda expressions and method references, you can easily define custom sorting criteria based on the properties of your objects. In this guide, we’ll explore how to sort a stream of objects in Java 8, covering various scenarios including sorting by a single field, multiple fields, and handling null values.

Table of Contents

  • Problem Statement
  • Solution Steps
  • Java Program
    • Sorting a Stream of Objects by a Single Field
    • Sorting a Stream of Objects by Multiple Fields
    • Sorting a Stream of Objects with Null Values
  • Advanced Considerations
  • Conclusion

Problem Statement

The task is to create a Java program that:

  • Accepts a collection of objects.
  • Sorts the collection using the Stream API based on specific criteria.
  • Outputs the sorted collection.

Example 1:

  • Input: List of Student objects [Student("Raj", 25), Student("Anita", 30), Student("Vikram", 22)], Sort by age.
  • Output: Sorted list [Student("Vikram", 22), Student("Raj", 25), Student("Anita", 30)].

Example 2:

  • Input: List of Student objects [Student("Raj", 25), Student("Anita", 30), Student("Vikram", 22)], Sort by name.
  • Output: Sorted list [Student("Anita", 30), Student("Raj", 25), Student("Vikram", 22)].

Solution Steps

  1. Create a Collection: Start with a collection of objects that you want to sort.
  2. Sort the Collection Using the Stream API: Use the sorted() method to sort the collection based on the desired criteria.
  3. Display the Result: Print the sorted collection.

Java Program

Sorting a Stream of Objects by a Single Field

Sorting a list of objects by a single field, such as sorting students by their age, is straightforward using the sorted() method.

import java.util.List;
import java.util.stream.Collectors;

/**
 * Java 8 - Sort a Stream of Objects by a Single Field
 * Author: https://www.rameshfadatare.com/
 */
public class SortStreamBySingleField {

    public static void main(String[] args) {
        // Step 1: Create a list of students
        List<Student> students = List.of(
            new Student("Raj", 25),
            new Student("Anita", 30),
            new Student("Vikram", 22)
        );

        // Step 2: Sort the list by age
        List<Student> sortedByAge = students.stream()
            .sorted((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge()))
            .collect(Collectors.toList());

        // Step 3: Display the result
        sortedByAge.forEach(student -> 
            System.out.println(student.getName() + ": " + student.getAge())
        );
    }
}

// Custom class Student
class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

Output

Vikram: 22
Raj: 25
Anita: 30

Explanation

  • The stream() method creates a stream from the list of Student objects.
  • The sorted((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge())) method sorts the stream by the age field.
  • The sorted students are collected into a list using Collectors.toList() and printed.

Sorting a Stream of Objects by Multiple Fields

When sorting by multiple fields, such as sorting students by age and then by name, you can chain comparators.

import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;

/**
 * Java 8 - Sort a Stream of Objects by Multiple Fields
 * Author: https://www.rameshfadatare.com/
 */
public class SortStreamByMultipleFields {

    public static void main(String[] args) {
        // Step 1: Create a list of students
        List<Student> students = List.of(
            new Student("Raj", 25),
            new Student("Anita", 30),
            new Student("Vikram", 22),
            new Student("Anita", 22)
        );

        // Step 2: Sort the list by age, then by name
        List<Student> sortedByAgeAndName = students.stream()
            .sorted(Comparator.comparingInt(Student::getAge)
                .thenComparing(Student::getName))
            .collect(Collectors.toList());

        // Step 3: Display the result
        sortedByAgeAndName.forEach(student -> 
            System.out.println(student.getName() + ": " + student.getAge())
        );
    }
}

// Custom class Student
class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

Output

Anita: 22
Vikram: 22
Raj: 25
Anita: 30

Explanation

  • The sorted(Comparator.comparingInt(Student::getAge).thenComparing(Student::getName)) method sorts the stream first by age and then by name.
  • The sorted students are collected into a list using Collectors.toList() and printed.

Sorting a Stream of Objects with Null Values

If your objects might contain null values, you can handle them explicitly in your comparator.

import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;

/**
 * Java 8 - Sort a Stream of Objects with Null Values
 * Author: https://www.rameshfadatare.com/
 */
public class SortStreamWithNullValues {

    public static void main(String[] args) {
        // Step 1: Create a list of students with some null names
        List<Student> students = List.of(
            new Student("Raj", 25),
            new Student(null, 30),
            new Student("Vikram", 22),
            new Student("Anita", 22)
        );

        // Step 2: Sort the list by name, handling nulls last
        List<Student> sortedByNameWithNullsLast = students.stream()
            .sorted(Comparator.comparing(Student::getName, 
                Comparator.nullsLast(Comparator.naturalOrder())))
            .collect(Collectors.toList());

        // Step 3: Display the result
        sortedByNameWithNullsLast.forEach(student -> 
            System.out.println(student.getName() + ": " + student.getAge())
        );
    }
}

Output

Anita: 22
Raj: 25
Vikram: 22
null: 30

Explanation

  • The Comparator.nullsLast(Comparator.naturalOrder()) method ensures that null values are placed at the end of the sorted list.
  • The stream is sorted by name, handling null values appropriately, and the result is printed.

Advanced Considerations

  • Reverse Order: If you need to sort in descending order, you can use Comparator.reverseOrder() or chain .reversed() to the comparator.

  • Performance Considerations: Sorting large streams can be resource-intensive. Consider the performance impact, especially when dealing with large datasets.

  • Parallel Streams: For large datasets, consider using parallel streams (parallelStream()) to improve performance when sorting.

Conclusion

This guide provides methods for sorting a stream of objects in Java 8, covering scenarios with single-field sorting, multi-field sorting, and handling null values. The Stream API, combined with comparators, offers a powerful and flexible way to sort collections of objects based on various criteria. Depending on your specific use case, you can choose the method that best fits your needs for sorting streams in Java.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top