英文:
Use java 8 stream api to do deep copy of array list but get build time error
问题
我在我的 Spring Boot 项目的模型类中使用了 lombok 库。
@Data
@Builder
public class Employee {
private String fullname;
private long someNumber;
private boolean isManager;
}
在另一个类中,我有一个员工列表:
List<Employee> employeeList = getListOfEmployees();
我想要创建一个 employeeList
的深拷贝,以下是我尝试过的方法:
步骤1:我在 Employee
类中创建了一个拷贝构造函数:
@Data
@Builder
public class Employee {
private String fullname;
private long someNumber;
private boolean isManager;
// 拷贝构造函数
public Employee(Employee employee) {
this.fullname = employee.fullname;
this.someNumber = employee.someNumber;
this.isManager = employee.isManager;
}
}
步骤2:我使用 Java 8 的流 API 来创建员工列表的深拷贝:
List<Employee> employeeListCopy = employeeList.stream().map(Employee::new).collect(Collectors.toList());
但是当我构建我的 Spring Boot 项目时,我遇到了错误:
错误:(13, 1) java: 无法将类 com.my.webapp.model.Employee 中的构造函数应用于给定类型;
必需的类型:com.my.webapp.Employee
找到的类型:java.lang.String,long,boolean
原因:实际参数列表与形式参数列表的长度不同
为什么会出现这个错误?如何消除这个深拷贝的错误?
英文:
I use lombok library in my spring-boot project's model classes.
@Data
@Builder
public class Employee {
private String fullname;
private long someNumber;
private boolean isManager;
}
In another class, I have a list of employees:
List<Employee> employeeList = getListOfEmployees();
I would like to create a deep copy of the employeeList
, the following things are what I tried:
step 1. I create a copy constructor in Employee
class:
@Data
@Builder
public class Employee {
private String fullname;
private long someNumber;
private boolean isManager;
// copy constructor
public Employee(Employee employee) {
this.fullname = employee.fullname;
this.someNumber = employee.someNumber;
this.isManager = employee.isManager;
}
}
step 2. I use Java 8 stream API to create a deep copy of the list of employees:
List<Employee> employeeListCopy = employeeList.stream().map(Employee::new).collect(Collectors.toList());
But when I build my sprint-boot project, I got error:
Error:(13, 1) java: constructor Employee in class com.my.webapp.model.Employee cannot be applied to given types;
required: com.my.webapp.Employee
found: java.lang.String,long,boolean
reason: actual and formal argument lists differ in length
Why? How to get rid of this error for my deep copy?
答案1
得分: 2
问题不在于 Stream API,而在于 lombok
。当你使用 @Builder
时,会调用一个构造函数:
public Employee build() {
return new Employee(fullname, someNumber, isManager);
}
在 EmployeeBuilder
内部调用(由 lombok 生成)。由于你已经提供了一个构造函数,lombok 将不会生成另一个构造函数(即:lombok 仅在没有已定义构造函数的情况下为生成器生成所需的构造函数)。解决方案相当简单,将 @AllArgsConstructor
添加到你的类中。
通常情况下,我个人不太喜欢 @Builder
,而是使用 @Accessors(chain = true)
替代:
@Setter
@Getter
@Accessors(chain = true)
static class Employee {
private String fullname;
private long someNumber;
private boolean isManager;
public Employee() {
}
// 拷贝构造函数
public Employee(Employee employee) {
fullname = employee.fullname;
someNumber = employee.someNumber;
isManager = employee.isManager;
}
}
然后你可以这样做:
Employee emp = new Employee()
.setFullname("")
.setManager(false)
.setSomeNumber(2L);
英文:
The problem is not in the Stream API, but in lombok
. When you use @Builder
, there will be a call to a constructor:
public Employee build() {
return new Employee(fullname, someNumber, isManager);
}
from within EmployeeBuilder
(that lombok will generate). Since you have already provided a constructor, lombok will not generate another one (i.e.: lombok will only generate the needed constructor for the Builder IFF there is not a constructor already defined). The solution is rather simple, add @AllArgsConstructor
to your class.
In general, I personally, am not a fan of @Builder
, I use @Accessors(chain = true)
instead:
@Setter
@Getter
@Accessors(chain = true)
static class Employee {
private String fullname;
private long someNumber;
private boolean isManager;
public Employee() {
}
// copy constructor
public Employee(Employee employee) {
fullname = employee.fullname;
someNumber = employee.someNumber;
isManager = employee.isManager;
}
}
And you can do:
Employee emp = new Employee()
.setFullname("")
.setManager(false)
.setSomeNumber(2L);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论