简体   繁体   English

在java 8中访问从第一个流到下一个流api的对象引用

[英]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. 我想在这里添加java 8 stream api而不是两个for循环但是如果你在try block看到有dept.getId()我无法在流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. getEmployeeV2()这里我创建了EmployeeV2对象。 But I not sure how I can pass Department to here so I can access department id. 但我不知道如何将部门传递到这里,以便我可以访问部门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. 由于EmployeeV2类的构造函数抛出异常,因此根据您需要的业务逻辑,您可以使用不同的选项来解决此问题。

First one is to catch the exception in your Lambda: 第一个是捕获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: 第二种方法是更新EmployeeV2的构造函数并抛出一些你不需要在Lambda中捕获的RuntimeException

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. 您也可以在外部方法中外包异常处理,就像您在问题中已经做过的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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