How to build new instance of Value object from existng one with updated collection property using Lombok Builder?

问题描述 投票:0回答:3

我正在使用具有集合属性的不可变对象。像这样的东西:

@Value
@Builder(toBuilder = true)
class Person {

    String name;
    @Singular
    Set<String> skills;

}

当我从现有的 Person 创建一个新实例但具有更新的技能时,集合似乎没有更新。

        Person jonh = Person.builder()
                .name("John")
                .build();
        System.out.println(jonh);

        Person johnUpgraded = jonh.toBuilder()
                .skill("Java")
                .skill("Spring")
                .build();
        System.out.println(johnUpgraded);

        Person johnDowngraded = johnUpgraded.toBuilder()
                .skills(Collections.emptySet())
                .build();
        System.out.println(johnDowngraded);

它打印:

Person(name=John, skills=[])
Person(name=John, skills=[Java, Spring])
Person(name=John, skills=[Java, Spring])

是否可以创建人的副本并设置其他技能?

非常感谢您考虑我的要求!

是否可以创建人的副本并设置其他技能?

java lombok
3个回答
0
投票

您可以先调用

clearSkills()
来完全重置该集合的内容。否则所有值保持不变;与
@Singular
所有setter方法都像“加法器”一样。


0
投票

首先,您的

.skills(Collections.emptySet())
方法只是在现有集合之上添加空集合。

如果你想清除它,只需使用 `clear() 方法:

//to make it work, add @Getter annotation on top of your Person class
johnUpgraded.getSkills().clear();

是否可以创建人的副本...

According to this answer

toBuilder()
method doesn't do deep copy.所以
jonh
johnUpgraded
johnDowngraded
是同一个对象。

要复制您的对象,您必须再次使用

Person.builder()
,如下所示:

        Person jonh = Person.builder()
                .name("John")
                .build();

        Person johnUpgraded = Person.builder()
                .name(jonh.getName()) 
                .skill("Java")
                .skill("Spring")
                .build();

更新:

克隆你的集合,根据前一个集合创建另一个。

.skill(new HashSet<>(jonh.getSkills()));

0
投票

您可以使用

@With
-er 干净地完成此操作。这个注解生成一个
with
方法,类似于 setter,但它会返回对象的一个新实例。在我看来,这是实现不可变对象的方法:

import lombok.With;

@Value
@Builder
static class Person {
    String name;
    @With
    @Singular
    Set<String> skills;
}

@Test
void test() {
    Person jonh = Person.builder()
            .name("John")
            .build();
    System.out.println(jonh);

    Person johnUpgraded = jonh.withSkills(Set.of(
            "Java",
            "Spring"
    ));
    System.out.println(johnUpgraded);
}
© www.soinside.com 2019 - 2024. All rights reserved.