Home > Enterprise >  Using Streams, see if a list contains a property of an object from another list
Using Streams, see if a list contains a property of an object from another list

Time:12-15

Jeez, I almost need another bit of help in how to phrase this question! New Java II student here, thanks in advance for your time.

I have a list of employees that look like this:

public class Employee {
    private String name;
    private String department;
}

And a list of Companies that look like this:

public class Company {  
    private String name;    
    List<Department> departments;
}

Department is just:

public class Department{    
    private String name;
    private Integer totalSalary;
}

So I'm tasked with streaming a list of employees that work for the same company. (Sorry for not saying before: the company is passed in to a fuction. It's the lone argument) It seemed easy when I first read it, but because of how the classes are set up, (Company with only a list of departments, and Employee with a single department, but no link between employee and company) I can stream to make a list of all Departments in a Company, but just don't know how to bring that back and match the employee's department string with any string from the departments that belong to the Company in question...

List<Department> deptsInCompany = companies.stream()
                .filter(s -> s.getName().equals(passedInCompany))
                .flatMap(s -> s.getDepartments().stream())              
                .collect(Collectors.toList());

I'm just not sure how to use that list of departments to backtrack and find the Employees in those departments. I think my ROOKIE mind can't get past wanting there to be a list of Employees in each department object, but there's not!

Any little nudge would be greatly appreciated! I promise to pay it forward when i've got some skill!!

CodePudding user response:

Assuming that you have a list of all employees and that all your model classes have getters for their properties, you can do the following:

public static void main(String[] args) {
    List<Company> companies = // Your list of Companies
    String passedInCompany = "Company";
    
    List<String> deptsNameInCompany = companies.stream()
            .filter(s -> s.getName().equals(passedInCompany))
            .flatMap(s -> s.getDepartments().stream())
            .map(Department::getName)
            .collect(Collectors.toList());

    List<Employee> employees = // All Employees
    List<Employee> employeesInCompanyDepts = employees.stream()
            .filter(employee -> deptsNameInCompany.contains(employee.getDepartment()))
            .collect(Collectors.toList());
}

Basically you need to collect all the Departments names and then find the Employees that have such Department name in its department property.

CodePudding user response:

Collect the department names of the (single) company with the given name into a Set (which is faster for lookup than a List).

Set<String> departmentNames = companies.stream()
    .filter(c -> c.getName().equals(companyName))
    .findFirst().get().getDepartments().stream()
    .map(Department::getName)
    .collect(Collectors.toSet());

Then remove all employees that aren't in those departments from the list.

employees.removeIf(e -> !departmentNames.contains(e.getDepartment()));

If you want to preserve the list of employees, filter and collect:

List<Employee> employeesInCompany = employees.stream()
    .filter(e -> departmentNames.contains(e.getDepartment()))
    .collect(Collectors.toList());
  • Related