在带有和不带有@Singular 注释的Collection 字段上使用复数方法时的不同效果

Different effect when using plural method on Collection field with and without @Singular annotation

我想要不可变的 myClass 对象。使用@Singular 注释的好的解决方案接缝。 问题是当我使用此注释时,方法 elements() 将元素附加到现有列表,而不是创建新列表:

假设我们有:

@Value
@Builder(toBuilder = true)
public class MyClass  {
    @Singular
    private List<String> elemets;
}

MyClass.builder()
.elemets(Arrays.asList("elem1"))
.elemets(Arrays.asList("elem2"))
.build();

如果没有@Singular 注释,我们在列表中有 elem2 使用@Singular 注释我们同时拥有elem1 和elem2,如果我只想拥有elem2,我必须在之前使用clearElements()。

为什么实现不同?我自己的实现可以使用@Singular吗?

使用 @Singular 注释我无法在 MyClassBuilder class 中实现 elemets(List elemets) 方法,因为我得到:"Manually adding a method that @Singular @Builder would generate is not supported. If you want to manually manage the builder aspect for this field/parameter, don't use @Singular."

首先让我说,使用 @Singular 不一定是最好的解决方案——这取决于您的用例。 但是,在大多数情况下,如果您想确保使用集合的 classes 的不变性,这是一个不错的选择。

@Singular 之所以如此,是因为 Lombok 设计师认为这样做是个不错的选择。我同意:它使两个 setter 方法的行为相似;在极少数情况下,您想要重置构建器中的元素,您可以使用 clear 方法。

@Singular 生成相当复杂的代码(参见 https://projectlombok.org/features/BuilderSingular 的示例)。这是为了确保效率和不变性等属性(在重用构建器生成多个对象时也是如此)。当您乱用该代码时,您很容易违反这些属性。 Lombok 阻止你这样做。

如果你真的想修改这方面,你有三个选择:

  • delombok生成器代码,复制到你的class,然后修改。
  • 添加另一个不同名称的方法,如 clearAndSetElements(List<String>)。但这可能更令人困惑。
  • 删除 @Singular 并自行实现 setter 方法。如果你想要 Lombok 的实现的属性,你将不得不在实现上付出一些努力;您可以使用 delomboked 代码作为灵感。