具有 Java 8 的 lambda 表达式的生成器
Builder with lambda expression for Java 8
我有两个 class 如下所述。
我想创建 class A
.
的两个实例
我想从现有实例 obj1 创建实例 obj2,并将 a3 属性的更新值设为 "Java"
.
我曾尝试使用 Builder 进行以下操作,但它不起作用。
A obj2 = obj1.builder().a3("Java").build();
我可以通过调用构造函数来完成,但我只想使用 Builder
模式。
@Builder(toBuilder = true)
@Data
class A {
String a1;
String a2;
String a3;
B b;
A(String b1, String b2, String b3, B b) {
this.a1 = b1;
this.a2 = b2;
this.a3 = b3;
this.b = b;
}
}
@Builder
@Data
class B {
String b1;
String b2;
String b3;
B(String b1, String b2, String b3) {
this.b1 = b1;
this.b2 = b2;
this.b3 = b3;
}
}
class Main {
public static void main(String[] args) {
B b = new B("a", "b", "b");
A obj1 = new A("a1", "b1", "b1", b);
A obj2 = new A("x1", "y1", "z1", b);
List<A> list= new ArrayList<>();
list.add(obj1);
list.add(obj2);
list.forEach(a -> {
a.toBuilder().a1("newA1").a2("newA2").build();
repository.save(a);
});
A obj3 = obj1.toBuilder().a3("Java").build();
}
}
如更新代码中所述,我有 A 列表,我想使用生成器更新列表中所有元素的 a1 and a2
属性。但是构建器不能很好地处理 lambda。
如果我将 setter 与以下代码一起使用,它工作正常。
list.forEach(a -> {
a.setA1("newA1");
a.setA2("newA2");
});
如果 Builder
和 Lambda
这条语句没有做任何事情
list.forEach(a -> {
a.toBuilder().a1("newA1").a2("newA2").build(); //<<<
repository.save(a);
});
您正在从旧对象创建一个新对象,然后将其丢弃。它不会对现有对象进行更改。考虑
list.stream()
.map(a -> a.toBuilder().a1("newA1").a2("newA2").build())
.forEach(repository::save);
用户@Michael 的回答已经修复了粘贴中的一些错误。
原因"it is not working"(请下次更具体)是您在执行空操作。
操作:
x.toBuilder().changeSomething().build()
创建一个新对象。它不修改对象:Builder 用于不可变对象;你不能修改它们。
因此,对于列表中的每个元素,您都从中派生一个构建器,进行一些修改,从中创建一个新对象,然后迅速将这个对象扔进垃圾箱。
尝试:
list.stream().map(a -> a.toBuilder().a1("newA1").build()).collect(Collectors.toList());
或更简单的遵循:
for (int i = 0; i < list.size(); i++) {
var withNewValue = list.get(i).toBuilder().a1("newA1").build();
list.set(i, withNewValue);
}
有时候旧方法是最好的方法。
我有两个 class 如下所述。
我想创建 class A
.
我想从现有实例 obj1 创建实例 obj2,并将 a3 属性的更新值设为 "Java"
.
我曾尝试使用 Builder 进行以下操作,但它不起作用。
A obj2 = obj1.builder().a3("Java").build();
我可以通过调用构造函数来完成,但我只想使用 Builder
模式。
@Builder(toBuilder = true)
@Data
class A {
String a1;
String a2;
String a3;
B b;
A(String b1, String b2, String b3, B b) {
this.a1 = b1;
this.a2 = b2;
this.a3 = b3;
this.b = b;
}
}
@Builder
@Data
class B {
String b1;
String b2;
String b3;
B(String b1, String b2, String b3) {
this.b1 = b1;
this.b2 = b2;
this.b3 = b3;
}
}
class Main {
public static void main(String[] args) {
B b = new B("a", "b", "b");
A obj1 = new A("a1", "b1", "b1", b);
A obj2 = new A("x1", "y1", "z1", b);
List<A> list= new ArrayList<>();
list.add(obj1);
list.add(obj2);
list.forEach(a -> {
a.toBuilder().a1("newA1").a2("newA2").build();
repository.save(a);
});
A obj3 = obj1.toBuilder().a3("Java").build();
}
}
如更新代码中所述,我有 A 列表,我想使用生成器更新列表中所有元素的 a1 and a2
属性。但是构建器不能很好地处理 lambda。
如果我将 setter 与以下代码一起使用,它工作正常。
list.forEach(a -> {
a.setA1("newA1");
a.setA2("newA2");
});
如果 Builder
和 Lambda
这条语句没有做任何事情
list.forEach(a -> {
a.toBuilder().a1("newA1").a2("newA2").build(); //<<<
repository.save(a);
});
您正在从旧对象创建一个新对象,然后将其丢弃。它不会对现有对象进行更改。考虑
list.stream()
.map(a -> a.toBuilder().a1("newA1").a2("newA2").build())
.forEach(repository::save);
用户@Michael 的回答已经修复了粘贴中的一些错误。
原因"it is not working"(请下次更具体)是您在执行空操作。
操作:
x.toBuilder().changeSomething().build()
创建一个新对象。它不修改对象:Builder 用于不可变对象;你不能修改它们。
因此,对于列表中的每个元素,您都从中派生一个构建器,进行一些修改,从中创建一个新对象,然后迅速将这个对象扔进垃圾箱。
尝试:
list.stream().map(a -> a.toBuilder().a1("newA1").build()).collect(Collectors.toList());
或更简单的遵循:
for (int i = 0; i < list.size(); i++) {
var withNewValue = list.get(i).toBuilder().a1("newA1").build();
list.set(i, withNewValue);
}
有时候旧方法是最好的方法。