0

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.

2 Answers 2

2

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());
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.