使用 Java Stream api 从对象层次结构中提取数据 [关闭]

Posted

技术标签:

【中文标题】使用 Java Stream api 从对象层次结构中提取数据 [关闭]【英文标题】:Extract data from object hierarchy using Java Stream api [closed] 【发布时间】:2021-09-14 20:41:31 【问题描述】:

无法使用 Stream 来列出对象层次结构。 这是我要检索数据的对象的类图:

@Data
class Institution 
  private List<Orgs> org; 


@Data
class Orgs 
  private String orgName;
  private List<Employee> emp;


@Data
class Employee 
  private String id;
  private String name;


class Main 
    
    public static void main(String args[]) 
        //I want to retrieve an employee name as "MARK"
        //I want to retrieve an employee name as "MARK" from OrgName as "BUSINESS"
        how would i acheive this??
    

【问题讨论】:

到目前为止您尝试了哪些方法,您在哪里卡住了? 【参考方案1】:

有两个问题需要解决。

    Orgs 可以有更多实例,orgNameBUSINESS Employee 可以有更多实例,nameMARK

这意味着,可以有 3 个 Orgs 和这样的 orgName,并且在每个中,假设有 4 个名为 MARK 的人。

那么解决方案将根据您的需求而有所不同:

所有 MARK 员工来自所有 BUSINESS-命名组织。将它们全部收集到一个部落中。这是迄今为止最简单的实现:

List<Employee> eachMarkFromEachBusiness = institution.getOrg()
     .stream()                                           // Stream<Orgs>
     .filter(org -> "BUSINESS".equals(org.getOrgName())) // Stream<Orgs>
     .flatMap(org -> org.getEmp().stream())              // Stream<Employee>
     .filter(emp -> "MARK".equals(emp.getName()))        // Stream<Employee>
     .collect(Collectors.toList());                      // List<Empoloyee>

所有 MARK 员工来自第一个 BUSINESS-named 组织找到(如果您需要特定的,您需要包含一个额外的过滤器,基于例如,假设增值税号或 ID)。

List<Employee> eachMarkFromSingleBusiness = institution.getOrg()
     .stream()                                           // Stream<Orgs>
     .filter(org -> "BUSINESS".equals(org.getOrgName())) // Stream<Orgs>
     .findFirst()                                        // Optional<Orgs>
     .map(Orgs::getEmp)                                  // Optional<List<Employee>>
     .stream()                                           // Stream<List<Employee>>
     .flatMap(empList -> empList                         // Stream<Employee>
         .stream()                                       // .. Stream<Employee>
         .filter(emp -> "MARK".equals(emp.getName())))   // .. Stream<Employee>
     .collect(Collectors.toList());                      // List<Employee>

第一个 MARK 员工来自第一个 BUSINESS-命名组织找到。同样,如果您想比找出第一个更具体,您需要在OrgsEmployeeboth 上提供额外的过滤器either。只要不存在MARK 或不存在BUSINESS,就让返回类型为Optional

Optional<Employee> singleMarkSingleBusiness = institution.getOrg()
     .stream()                                           // Stream<Orgs>
     .filter(org -> "BUSINESS".equals(org.getOrgName())) // Stream<Orgs>
     .findAny()                                          // Optional<Orgs>
     .map(Orgs::getEmp)                                  // Optional<List<Employee>>
     .stream()                                           // Stream<List<Employee>>
     .flatMap(empList -> empList                         // Stream<Employee>
         .stream()                                       // .. Stream<Employee>
         .filter(emp -> "MARK".equals(emp.getName())))   // .. Stream<Employee>
     .findFirst();                                       // Optional<Employee>

请注意,Optional::stream 方法在 java-9 和更新版本中可用。只要您标记了java-8,这里有一个解决方法:

java-9 及更新版本:

Stream<String> stream = new ArrayList<String>()         // List<String>
        .stream()                                       // Stream<String>
        .findFirst()                                    // Optional<String>
        .stream();                                      // Stream<String>

java-8:

Stream<String> stream = new ArrayList<String>()         // List<String>
        .stream()                                       // Stream<String>
        .findFirst()                                    // Optional<String>
        .map(Stream::of)                                // Optional<Stream<String>>
        .orElse(Stream.empty());                        // Stream<String>

【讨论】:

以上是关于使用 Java Stream api 从对象层次结构中提取数据 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

java8新特性-Stream(API)

java8新特性-Stream(API)

java Streams API介绍

Java8学习笔记--Stream API详解[转]

Java8使用Stream API转换Map遇到的2种异常报错和解决思路

使用Java8 Stream API对Map按键或值进行排序