当前位置: 首页 > 知识库问答 >
问题:

当处理不可变对象时,如何最好地返回带有修改字段的副本?

璩慎之
2023-03-14

Java 8的Streams API更倾向于功能性地编写代码,而不是强制性地编写代码。正如我们所知,不可变性提供了许多好处,因此,我尽量使对象在任何可行的地方都是不可变的。在日常编程中,我发现自己处于一种情况,我想“设置”一个值。我的对象是不可变的,所以我需要创建一个新的对象并初始化构造函数中的字段。

我使用project Lombok,它提供了诸如@value这样的注释,它本质上使对象不可变。它还具有@builder,它使用构建器模式为不可变对象提供构建器,将fluent API中未提及的字段设置为null

@builder批注有一个名为toBuilder的字段,当该字段设置为true时,将提供toBuilder()方法,该方法返回用对象中的字段填充的生成器,开发人员可以在其中“设置”值、调用builder()并返回新对象。

例如。要创建具有修改的字段的不可变对象的列表,我将执行以下操作:

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

import lombok.Builder;
import lombok.Value;

public class SOExample {

    @Value
    @Builder(toBuilder = true)
    private static class Person {
        private final String forename;
        private final String surname;
        private final int age;
        private final int heightInCm;
    }

    public static void main(String[] args) {
        List<Person> people = Arrays.asList(Person.builder()
                .forename("stack")
                .surname("overflow")
                .age(21)
                .heightInCm(180)
                .build());
        people.stream()
                .map(p -> p.toBuilder()
                        .forename("updatedForename")
                        .build())
                .collect(Collectors.toList());
    }
}

如果不使用Lombok,这将需要大量的锅炉板代码。事实上,我已经查看了生成的代码,它既不小也不平凡。这导致我质疑自己。其他人是怎么做到的?我担心我漏掉了一个把戏。

考虑到上面的描述和示例,返回具有更新字段的不可变对象的副本的最佳方法是什么?在Streams API中如何使用它?

共有1个答案

董俊
2023-03-14

您可以按照新的Java 8 Time API的方式来实现,方法是添加withxxx()方法,例如localdatehas:

>

  • withyear(int year)-返回更改了年份的localdate的副本。

    withmonth(int month)-返回更改了月份的localdate的副本。

    withdayofmonth(int dayOfMonth)-返回更改了月份日期的localdate的副本。

  •  类似资料:
    • 我一直在研究猫鼬文档,但我找不到一种方法来实现我想要做的事情。考虑一个MangGDB用户集合。还可以考虑一个包含DB集合中所有字段的蒙古人用户模式。 现在,我想登录到控制台,所有用户,但属性已更改。有点像: 用户。图例(): 给定的异步类型。find()函数我不确定这是否可以实现。我来自C#和PHP背景,只处理关系数据库,这可以通过在用户类中使用只返回所需值的函数轻松实现。 能做到吗?!

    • 问题内容: 说我们有这个 是什么使该线程不安全?接下来是这个问题。 问题答案: 一旦安全发布,它就是线程安全的。例如,此程序可能会打印“不安全”(它可能不会使用hotspot / x86的组合)-如果您进行最终定格,则不会发生:

    • 问题内容: 我正在使用PuTTY运行: 有很多字段,这导致试图在终端中显示很多列。字段将换行到下一行,因此很难将字段名称与字段标题对齐。 在终端中查看此类数据有哪些解决方案? 我既没有也不想访问phpMyAdmin- 或任何其他GUI界面。我正在寻找这样的命令行解决方案:将MySQL查询结果保存到文本或CVS文件中 问题答案: 以代替 查询终止查询。例如: 此查询垂直显示行,如下所示:

    • 这是一个愚蠢的问题,但我正在开发一个AngularJS应用程序(一个简单的学校项目),我想知道是否有一种方法可以在chrome中运行JavaScript对象后,从chrome的开发工具中修改它。基本上,我有一个角色和一个怪物,我想编辑他们在战斗中的力量,以加快我的调试过程(避免在源代码中设置值,然后刷新页面)。 编辑:这就是答案。我只是不知道怎么找。:)

    • 我们有一个方法,其中我们收到一个

    • 假设我有一个Foo类和一个jax-rs FooResource,它将API公开给CRUD Foos。 Foo表示MongoDB文档。 在FooResource中,我将有如下内容: 问题是,json中的foo对象将只包含已经更改的字段,但我从来不知道它将是什么字段。 我使用带Panache扩展的Quarkus,我看到的唯一方法是从DB检索实体,然后检查从http请求接收到的foo对象中的每个字段,看