简体   繁体   中英

Access object reference from first stream to next stream api in java 8

I have below existing code which converting one object to another -

for(Department dept : company.getDepartments()) {
  if(!isEmpty(dept.getEmployees())) {
        for(Employee emp : dept.getEmployees()) {

        try {
            employyeV2List.add(new EmployeeV2(emp.getId(),  emp.getFirstName(),..., dept.getId()));
        } catch (ParseException e) {
            //error logger
        }

    }
  }

} 

I want add java 8 stream api here instead of two for loops but if you see in try block there is dept.getId() which I can not access in stream API. I tried below -

List<Employee> employees = company.getDepartment().stream().map(x -> x.getEmployees())
            .flatMap(x -> x.stream()).collect(Collectors.toList());


List<EmployeeV2> employeeV2List = employees.stream().map(x -> getEmployeeV2(x)).collect(Collectors.toList());

Here in getEmployeeV2() I am creating EmployeeV2 object. But I not sure how I can pass Department to here so I can access department id.

You may do it like so,

List<EmployeeV2> result = company.getDepartment().stream()
    .flatMap(d -> d.getEmployees().stream()
        .map(e -> new EmployeeV2(e.getId(), e.getFirstName(), d.getId())))
    .collect(Collectors.toList());

Since the constructor of your EmployeeV2 class is throwing an Exception you have different options to solve this depending on the business logic you need.

First one is to catch the exception in your Lambda:

List<EmployeeV2> result = company.getDepartment().stream()
        .flatMap(d -> d.getEmployees().stream()
                .map(e -> {
                    try {
                        return new EmployeeV2(e.getId(), e.getFirstName(), d.getId());
                    } catch (ParseException exception) {
                        return null;
                    }
                }))
        .filter(Objects::nonNull)
        .collect(Collectors.toList());

This has the advantage, that get get a list of all employees which could be created. But you wont notice a failure.

A second alternative is to update the constructor of EmployeeV2 and throw some kind of RuntimeException which you don't need to catch in the Lambda:

try {
    List<EmployeeV2> result = company.getDepartment().stream()
            .flatMap(d -> d.getEmployees().stream()
                    .map(e -> new EmployeeV2(e.getId(), e.getFirstName(), d.getId())))
            .collect(Collectors.toList());
} catch (UncheckedParseException exception) {
    // handle the exception
}

This one has the advantage that you will notice errors, but don't get a List of successful created employees.

I hope these two examples help you to decide whats the correct usage for your application. You also can outsource the exception handling in an external method, like you already did in your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM