ZetCode

Java record

last modified July 8, 2023

Java record tutorial shows how to work with record type in Java. Record is a type that is primarily used to hold immutable data.

A record is a type that is designed to hold immutable data. It is very useful for data analysis. The record type simplifies code and improves its readability. It removes unnecessary boilerplate.

record User(String name, String occupation) {
}

This is a definition of a simple record. The compiler automatically creates two final fields and two public read accessors. A public constructor is derived from the record parameters.

The compiler auto-generates hashCode, equals, and toString methods.

Java record cannot extend any class, cannot declare instance fields, and cannot be abstract. A record can implement interfaces. We can also define our own constructors and methods.

Other languages also have similar types. C# and F# have records, Scala case classes, and Kotlin data classes.

Java record simple example

The following is a simple example with a Java record.

com/zetcode/RecordEx.java
package com.zetcode;

public class RecordEx {

    public static void main(String[] args) {

        var u = new User("John Doe", "gardener");
        System.out.println(u);

        System.out.println(u.name());
        System.out.println(u.occupation());
    }
}

record User(String name, String occupation) {
}

The program defines a User record with two string parameters.

record User(String name, String occupation) {
}

The definition of a Java record is concise.

var u = new User("John Doe", "gardener");

A new instance of a record is created with the new keyword.

System.out.println(u);

We pass the record instance to the System.out.println, invoking record's toString method.

System.out.println(u.name());
System.out.println(u.occupation());

We call the two auto-generated getters.

User[name=John Doe, occupation=gardener]
John Doe
gardener

Java record compare with equals

Java record auto-generates the equals method. It provides a value-based equality.

com/zetcode/RecordEx.java
package com.zetcode;

public class RecordEx {

    public static void main(String[] args) {

        var u = new User("John Doe", "gardener");
        var u2 = new User("Roger Roe", "driver");
        var u3 = new User("John Doe", "gardener");

        if (u.equals(u2)) {
            System.out.println("users are equal");
        } else {
            System.out.println("users are not equal");
        }
        
        if (u.equals(u3)) {
            System.out.println("users are equal");
        } else {
            System.out.println("users are not equal");
        }
    }
}

record User(String name, String occupation) {
}

The program compares three User record types.

users are not equal
users are equal

Java sort records

The next example sorts records.

com/zetcode/RecordEx.java
package com.zetcode;

import java.util.Comparator;
import java.util.List;

public class RecordEx {

    public static void main(String[] args) {

        var users = List.of(new User("John", "Doe", 1230),
                new User("Lucy", "Novak", 670),
                new User("Ben", "Walter", 2050),
                new User("Robin", "Brown", 2300),
                new User("Amy", "Doe", 1250),
                new User("Joe", "Draker", 1190),
                new User("Janet", "Doe", 980),
                new User("Albert", "Novak", 1930));

        var sorted = users.stream().sorted(Comparator.comparingInt(User::salary)).toList();
        System.out.println(sorted);
    }
}

record User(String fname, String lname, int salary) {
}

We have a User record with three arguments; we sort the users by their salaries.

var sorted = users.stream().sorted(Comparator.comparingInt(User::salary)).toList();

We use Java stream to sort the data.

Java customize record

We can customize record types by overriding methods or defining custom ones.

com/zetcode/RecordEx.java
package com.zetcode;

import java.util.List;

public class RecordEx {

    public static void main(String[] args) {

        var users = List.of(new User("John", "Doe", 1230),
                new User("Lucy", "Novak", 670),
                new User("Ben", "Walter", 2050),
                new User("Robin", "Brown", 2300),
                new User("Amy", "Doe", 1250),
                new User("Joe", "Draker", 1190),
                new User("Janet", "Doe", 980),
                new User("Albert", "Novak", 1930));

        var sorted = users.stream().sorted().toList();
        System.out.println(sorted);
    }
}

record User(String fname, String lname, int salary) implements Comparable<User> {
    @Override
    public int compareTo(User u) {
        return this.lname.compareTo(u.lname);
    }
}

The program defines a custom comparator. The default comparison of the User type is by last name.

record User(String fname, String lname, int salary) implements Comparable<User> {
    @Override
    public int compareTo(User u) {
        return this.lname.compareTo(u.lname);
    }
}

The record implements the Comparable interface and overrides the compareTo method where we compare the users' last names.

In this article we have worked with Java record type.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Java tutorials.