Java 使用lombok从现有对象构建对象
假设我有一个lombok注释类,比如Java 使用lombok从现有对象构建对象,java,lombok,Java,Lombok,假设我有一个lombok注释类,比如 @Builder class Band { String name; String type; } 我知道我能做到: Band rollingStones = Band.builder().name("Rolling Stones").type("Rock Band").build(); 有没有一种简单的方法可以使用现有对象作为模板创建Foo对象并更改其属性之一 比如: Band nirvana = Band.builder(rollingS
@Builder
class Band {
String name;
String type;
}
我知道我能做到:
Band rollingStones = Band.builder().name("Rolling Stones").type("Rock Band").build();
有没有一种简单的方法可以使用现有对象作为模板创建Foo对象并更改其属性之一
比如:
Band nirvana = Band.builder(rollingStones).name("Nirvana");
我在lombok文档中找不到这一点。您可以使用
toBuilder
参数为实例提供toBuilder()
方法
@Builder(toBuilder=true)
class Foo {
int x;
...
}
Foo f0 = Foo.builder().build();
Foo f1 = f0.toBuilder().x(42).build();
发件人:
如果使用@Builder生成生成器以生成您自己类的实例(除非将@Builder添加到不返回您自己类型的方法中,否则始终是这种情况),则可以使用@Builder(toBuilder=true)在类中生成名为toBuilder()的实例方法;它创建一个新的生成器,该生成器以该实例的所有值开始
免责声明:我是lombok开发者
有没有一种简单的方法可以使用现有对象作为模板创建Foo对象,并更改其一个属性?
(强调矿山)
如果您确实想更改单个属性,那么有一种更好、更高效的方法:
@With
class Band {
String name;
String type;
}
Band nirvana = rollingStones.withName("Nirvana");
wither不会创建垃圾,但它只能更改单个字段。要更改许多字段,可以使用
withA(a).withB(b).withC(c)....
并产生成吨的垃圾(都是中间结果),但比toBuilder
更高效、更自然
注:lombok的旧版本使用了
@Wither
注释。请参阅。您可能还需要使用com.fasterxml.jackson.databind.ObjectMapper创建对象的副本
@AllArgsConstructor
@Setter
class Band {
String name;
String type;
}
ObjectMapper objectMapper = new ObjectMapper(); //it's configurable
objectMapper.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
objectMapper.configure( SerializationFeature.FAIL_ON_EMPTY_BEANS, false );
Band rollingStones = new Band("Rolling Stones", "Rock Band");
Band nirvana = objectMapper.convertValue( rollingStones, Band.class);
nirvana.setName("Nirvana");
它可以很容易地包装在一些实用方法中,以便在整个项目中使用,例如
ConvertUtils.clone(rollingStones,Band.class)
@Mustafa还有@Wither
,它对于单字段更改更有效:Foo f1=f0.withX(42)
@maaartinus我认为@Wither
使用*方法生成,该方法总是返回一个新对象,而不是设置现有对象的字段。这效率很低。@MGhostSoft我显然认为创建一个新对象是他们的目标。因此,随着不可变对象的使用越来越多,我们变得非常普遍++×对于更改单个字段,@Wither
是最佳选择。超过两个时,toBuilder
获胜。请参阅下面我的答案。对于零字段(即没有任何更改的对象副本),@Wither
根本不起作用,但.toBuilder().build()
将是完美的答案!它真的会产生那么多垃圾吗?我认为除了要替换的字段之外,所有的都是浅拷贝(这取决于这样一个概念,即如果你想要的话,你将使对象不可变)。“垃圾”主要是被丢弃的顶级对象的引用(尽管我猜很多原语也会导致更多的垃圾)。@jm0当然,它们都是浅拷贝。我所说的“垃圾吨”是指一系列n
调用的n-1
对象。一个对象的成本大约为几个字节加上每个引用4或8字节加上每个原语1到8字节。所以我们说的是每次调用几十个字节。通常没什么大不了的。