【问题标题】:Extract data from object hierarchy using Java Stream api [closed]使用 Java Stream api 从对象层次结构中提取数据 [关闭]
【发布时间】: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??
}
}
【问题讨论】:
标签:
java
java-8
functional-programming
java-stream
【解决方案1】:
有两个问题需要解决。
-
Orgs 可以有更多实例,orgName 为 BUSINESS
-
Employee 可以有更多实例,name 为 MARK
这意味着,可以有 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-命名组织找到。同样,如果您想比找出第一个更具体,您需要在Orgs 或Employee 或both 上提供额外的过滤器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>