使用 java 8 stream api 进行数组列表的深度复制,但出现构建时错误

Use java 8 stream api to do deep copy of array list but get build time error

我在 spring-boot 项目的模型中使用 lombok 库 classes.

@Data
@Builder
public class Employee {

    private String fullname;
    private long someNumber;
    private boolean isManager;
}

在另一个 class 中,我有一个员工列表:

List<Employee> employeeList = getListOfEmployees();

我想创建 employeeList 的深拷贝,以下是我尝试过的:

第 1 步。我在 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;
    }
}

第 2 步。我使用 Java 8 流 API 创建员工列表的深拷贝:

List<Employee> employeeListCopy = employeeList.stream().map(Employee::new).collect(Collectors.toList());

但是当我构建 sprint-boot 项目时,出现错误:

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

为什么?如何为我的深拷贝消除这个错误?

问题不在流 API 中,而在 lombok 中。当你使用@Builder时,会调用一个构造函数:

public Employee build() {
      return new Employee(fullname, someNumber, isManager);
}

来自 EmployeeBuilder(lombok 将生成)。由于您已经提供了一个构造函数,因此 lombok 将不会生成另一个构造函数(即:lombok 将 为 Builder IFF 生成所需的构造函数,因为尚未定义构造函数)。解决方法很简单,将 @AllArgsConstructor 添加到 class。

总的来说,我个人不是@Builder的粉丝,我用@Accessors(chain = true)代替:

@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;
    }
}

你可以这样做:

Employee emp = new Employee()
        .setFullname("")
        .setManager(false)
        .setSomeNumber(2L);