Java Record Class Example

1. Introduction

In this blog post, we delve deeper into the Java record class, introduced in Java 16 as a feature to streamline the modeling of immutable data. We'll explore complex use cases of records, including validation, custom methods, and their usage in collections and streams.

Definition

A Java record is a special type of class in Java. It is a final class that automatically implements equals(), hashCode(), and toString() methods. Records aim to simplify the definition of immutable data aggregates.

2. Example 1

Steps:

1. Define a record with required components.

2. Create instances of the record.

3. Utilize record instances in a program.

4. Observe the automatic implementation of standard methods like toString().

Code Program:

// Define a record named 'Person'
public record Person(String name, int age) {}

public class Main {
    public static void main(String[] args) {
        // Creating an instance of the Person record
        Person person = new Person("Alice", 30);

        // Using the toString method provided by the record
        System.out.println(person);
    }
}

Output:

Person[name=Alice, age=30]

Explanation:

1. The Person record is defined with two components: name (a String) and age (an int).

2. An instance of Person is created with the name "Alice" and age 30.

3. System.out.println(person); invokes the toString() method, which is automatically provided by the record. This method returns a string representation of the record's state.

4. The output shows the toString representation of the Person object, demonstrating how records simplify the creation of immutable data classes.

3. Example 2

In this example, we'll explore complex use cases of records, including validation, custom methods, and their usage in collections and streams.

Steps:

1. Define complex records with validation and custom methods.

2. Use records with Java Collections and Streams.

3. Demonstrate the usage in a more practical scenario.

Code Program:

// Record with validation in the constructor
public record Product(String name, double price) {
    public Product {
        if (price < 0) {
            throw new IllegalArgumentException("Price must be positive");
        }
    }

    // Custom method to display product info
    public String display() {
        return "Product: " + name + ", Price: $" + price;
    }
}

// Using Record with Collections and Streams
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Product> products = List.of(
            new Product("Laptop", 999.99),
            new Product("Smartphone", 499.99)
        );

        // Filtering and displaying products using streams
        String expensiveProducts = products.stream()
            .filter(p -> p.price() > 500)
            .map(Product::display)
            .collect(Collectors.joining(", "));

        System.out.println(expensiveProducts);
    }
}

Output:

Product: Laptop, Price: $999.99

Explanation:

1. The Product record includes a compact constructor for validating the price field, ensuring it is not negative.

2. A custom method display is defined in the Product record, providing a formatted string of the product's details.

3. A list of Product instances is created using List.of.

4. The Stream API processes this list, filtering products with a price above 500 and mapping each product to its display string.

5. The output shows the products that meet the filter criteria, illustrating the integration of records with collections and functional programming.


Comments