ZetCode

Java 记录 (record)

上次修改时间:2024 年 3 月 8 日

在本文中,我们将展示如何在 Java 中使用记录类型。记录是一种主要用于保存不可变数据的类型。

记录是一种旨在保存不可变数据的类型。它对于数据分析非常有用。记录类型简化了代码并提高了其可读性。 它消除了不必要的样板代码。

record User(String name, String occupation) {
}

这是一个简单记录的定义。 编译器会自动创建两个 final 字段和两个公共只读访问器。 一个公共构造函数是从记录参数派生的。

编译器会自动生成 hashCodeequalstoString 方法。

Java 记录不能扩展任何类,不能声明实例字段,也不能是抽象的。 记录可以实现接口。 我们还可以定义自己的构造函数和方法。

其他语言也有类似的类型。 C# 和 F# 有 records,Scala 有 case classes,Kotlin 有 data classes。

简单示例

以下是一个带有 Java 记录的简单示例。

Main.java
void main() {

    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) {
}

该程序定义了一个带有两个字符串参数的 User 记录。

record User(String name, String occupation) {
}

Java 记录的定义简洁明了。

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

使用 new 关键字创建一个记录的新实例。

System.out.println(u);

我们将记录实例传递给 System.out.println,从而调用记录的 toString 方法。

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

我们调用两个自动生成的 getter。

$ java Main.java
User[name=John Doe, occupation=gardener]
John Doe
gardener

比较记录

Java 记录会自动生成 equals 方法。 它提供了一个基于值的相等性比较。

Main.java
void main() {

    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) {
}

该程序比较了三个 User 记录类型。

$ java Main.java
users are not equal
users are equal

排序记录

下一个示例对记录进行排序。

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

void main() {

    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) {
}

我们有一个带有三个参数的 User 记录; 我们按工资对用户进行排序。

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

我们使用 Java 流来对数据进行排序。

自定义记录

我们可以通过重写方法或定义自定义方法来自定义记录类型。

Main.java
import java.util.List;

void main() {

    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);
    }
}

该程序定义了一个自定义比较器。 User 类型的默认比较是按姓氏。

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

该记录实现了 Comparable 接口,并重写了 compareTo 方法,我们在该方法中比较用户的姓氏。

过滤记录

下一个示例过滤记录列表。

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

void main() {

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

    var filtered = users.stream().filter(e -> e.salary() > 2000)
            .collect(Collectors.toList());
    System.out.println(filtered);
}

record User(String fname, String lname, int salary) {
    public static User of(String fname, String lname, int salary) {
        return new User(fname, lname, salary);
    }
}

我们有一个 User 记录列表。 我们按工资过滤用户。

var filtered = users.stream().filter(e -> e.salary() > 2000)
        .collect(Collectors.toList());

我们过滤掉所有工资大于 2000 的用户。

$ java Main.java
[User[fname=Ben, lname=Walter, salary=2050], User[fname=Robin, lname=Brown, salary=2300]]

来源

Java 记录 - 语言参考

在本文中,我们使用了 Java 记录类型。

作者

我叫 Jan Bodnar,是一名充满激情的程序员,拥有丰富的编程经验。 我自 2007 年以来一直在撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有Java教程