我总是努力使我的代码完全不可变,而根本不使用setter。
当我需要更新对象,dto或实体时,我使用@Builder(toBuilder = true)
而不是setter。
public Car updateCar(final String id) {
final Car existing = carRepository.getById(id);
final Car.CarBuilder builder = existing.toBuilder().make("Mercedes-Benz");
if (anyCondition) {
builder.status("READY");
}
final Car updatedCar = builder.build();
return carRepository.save(updatedCar);
}
我想问一下,从性能角度来看,不是将值设置为已经实例化的对象,而是创建一个新对象,这真的很糟糕吗?
也许在上面的代码中,它并不重要,但我也可能需要更改集合中所有对象中的一个字段,因此空间复杂度将是线性的。
你更喜欢什么方法:setters或toBuilder?
P.S。:上面的代码片段只是为了更好地理解我如何利用toBuilder
我想问一下,从性能角度来看,不是将值设置为已经实例化的对象,而是创建一个新对象,这真的很糟糕吗?
你问我们和你自己这个错误的问题。 你不应该真正关心这种简单的数据载体类的性能。 基准(见JMH)并看到。
但从纯粹的理论角度来看,唯一的开销是创建另一个对象(内存中的大小取决于其成员的布局),将原始值/引用从构建器实例传递到结果实例的附加步骤(也许也是更多的GC工作?我甚至不会考虑这一点)。 因此有一些CPU周期。
另请参阅qazxsw poi,看看有多少人和公司正在使用它,并问自己,对于您的简单用例,您是否应该考虑提出这个问题。
上这堂课吧
Immutables
大小约为public class Car {
private String maker;
private int year;
private int kms;
// Getter - setters
}
字节。
现在,使用诸如的构建器
16 + 4 + 4 + 4 = 28
大小仍然约为public class CarBuilder {
private String maker;
private int year;
private int kms;
public CarBuilder setMaker(final String maker) {
this.maker = maker;
return this;
}
public CarBuilder setYear(final int year) {
this.year = year;
return this;
}
public CarBuilder setKms(final int kms) {
this.kms = kms;
return this;
}
public Car createCar() {
return new Car(maker, year, kms);
}
}
字节。
这意味着您将使用构建器至少将堆中使用的字节加倍。
但是,您需要考虑的是Java是基于参考的。这意味着所有创建的对象的指针将被简单地复制到生成的16 + 4 + 4 + 4 = 28
实例。对象在内存中仍然是唯一的。
在您编辑之后,您可能要做的是对象池?
在这种情况下,请考虑Car
。