Reputation: 1573
I have a List
of Employee object populated from a Json.
{
"emp": [
{
"name": "John",
"id": "123",
"reportingEmp": [
{
"name": "Mark",
"id": "342"
},
{
"name": "Mike",
"id": "342"
},
{
"name": "Lindsey",
"id": "342"
}
]
},
{
"name": "Steve",
"id": "123"
},
{
"name": "Andrew",
"id": "123"
}
]
}
class Employee {
private String name;
private String id;
private List<Employee> reportingEmp;
}
Now I wanted to get the names of all employess including the reporting employees in a stream.
I can use the below to get all the employees but it would miss the reporting employees
List<String> names = emp.stream().map(Employee::getName).collect(toList());
But the above would give only John,Steve and Andrew
but I want the below list
John
Mark
Mike
Lindsey
Steve
Andrew
Upvotes: 0
Views: 460
Reputation: 271635
flatMap
is the thing to use, when you want to map one thing (an Employee
) to multiple things (the employee's name + all the reporting employees' names).
In the flatMap
lambda, you just need to create a stream that contains the things you want to map that employee to, so:
List<String> names = employees.stream().flatMap(emp ->
Stream.concat(
// the employee's name,
Stream.of(emp.getName()), // and
// the employee's reporting employees' names
emp.getReportingEmp().stream().map(Employee::getName)
)
).collect(Collectors.toList());
If getReportingEmp
can return null
, then you can do:
List<String> names = employees.stream().flatMap(emp ->
Stream.concat(
Stream.of(emp.getName()),
Optional.ofNullable(emp.getReportingEmp()).map(
x -> x.stream().map(Employee::getName)
).orElse(Stream.of())
)
).collect(Collectors.toList());
Upvotes: 1