Using CompletableFuture to build an object with multiple methods

Nan*_*nor 5 java

I'm trying to understand CompletableFuture and how I can utilise it to build an object with information obtained from several endpoints. I've come across a few examples but none are quite tailored to my problem. For example, this one is running the same method in parallel to get a list of strings where I want to run multiple methods in parallel to build and return an object.

I've created a simple DTO for an employee:

@Builder
@Data
@AllArgsConstructor
public class EmployeeDTO {

    private String name;
    private String accountNumber;
    private int salary;

}
Run Code Online (Sandbox Code Playgroud)

I've created a service to mimic calls to three separate APIs to set the values of the DTO with a considerable wait time:

public class EmployeeService {

    public EmployeeDTO setName() {
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return EmployeeDTO.builder().name("John Doe").build();
    }

    public EmployeeDTO setAccountNumber() {
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return EmployeeDTO.builder().accountNumber("1235").build();
    }

    public EmployeeDTO setSalary() {
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return EmployeeDTO.builder().salary(100000).build();
    }
}
Run Code Online (Sandbox Code Playgroud)

I can supplyAsync all three of the methods and then run allOf but it doesn't do anything:

    private void run() {
        EmployeeService employeeService = new EmployeeService();

        CompletableFuture<EmployeeDTO> employeeCfWithName = CompletableFuture
                .supplyAsync(employeeService::setName);
        CompletableFuture<EmployeeDTO> employeeCfWithAccountNumber = CompletableFuture
                .supplyAsync(employeeService::setAccountNumber);
        CompletableFuture<EmployeeDTO> employeeCfWithSalary = CompletableFuture
                .supplyAsync(employeeService::setSalary);

        CompletableFuture allCompletableFutures = CompletableFuture.allOf(employeeCfWithName, employeeCfWithAccountNumber, employeeCfWithSalary);
    }
Run Code Online (Sandbox Code Playgroud)

How can I combine the results into one EmployeeDTO?

小智 2

您必须将三个CompletableFutures 的结果合并为一个EmployeeDTO. 这并不是由 神奇地完成的allOf

尝试这样的事情(未经测试):

CompletableFuture allCompletableFutures = CompletableFuture.allOf(
  employeeCfWithName, employeeCfWithAccountNumber, employeeCfWithSalary);

// Wait for all three to complete.
allCompletableFutures.get();

// Now join all three and combine the results.
EmployeeDTO finalResult = EmployeeDTO.builder()
  .name(new employeeCfWithName.join())
  .accountNumber(new employeeCfWithAccountNumber.join())
  .salary(new employeeCfWithSalary.join())
  .build();
Run Code Online (Sandbox Code Playgroud)

这看起来有点傻。我们在每个方法中都使用一个构建器,只是为了使用第四个构建器组合它们的结果。