Используйте java 8 stream api, чтобы сделать глубокое копирование списка массивов, но получите ошибку времени сборки - PullRequest
3 голосов
/ 07 апреля 2020

Я использую библиотеку 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;

    // copy constructor
    public Employee(Employee employee) {
        this.fullname = employee.fullname;
        this.someNumber = employee.someNumber;
        this.isManager = employee.isManager;
    }
}

шаг 2. Я использую потоковый API Java 8 для создания полной копии списка сотрудников:

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

Почему? Как избавиться от этой ошибки для моей глубокой копии?

1 Ответ

2 голосов
/ 07 апреля 2020

Проблема не в Stream API, а в lombok. Когда вы используете @Builder, будет вызываться конструктор:

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

из EmployeeBuilder (который сгенерирует lombok). Поскольку вы уже предоставили конструктор, lombok не будет генерировать другой (т.е. lombok будет только сгенерировать необходимый конструктор для IFF-файла Builder, если конструктор еще не определен). Решение довольно простое, добавьте @AllArgsConstructor в ваш класс.

В общем, я лично не фанат @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);
...