Marty
Marty

Reputation: 117

filtering of values in list based on values in set

I'm trying to use java 8 to solve the following issue. Say I have the following (A and B are custom classes)

ArrayList<A> skills;
HashSet<B> workCenters;

What I need to do is to find whether value a.getDepartment() which is a String also contained in B which also has a method String getDepartment() and then to collect those into new List<A>.

I tried such:

 List<A> collect = skills.stream()
     .filter(s -> workCenters.contains(s.getDepartment())
     .collect(Collectors.toList());

but in this case i don't do it right because I couldn't retrieve getDepartment() from workCenters. What would be the correct solution?

Upvotes: 3

Views: 1896

Answers (4)

Oleg Cherednik
Oleg Cherednik

Reputation: 18245

List<B> workCenters = Collections.emptyList();
List<A> skills = Collections.emptyList();

Set<String> workCenterDepartments = workCenters.stream().map(B::getDepartment).collect(Collectors.toSet());
List<A> skillsWithWorkCenterDept = new ArrayList<>(skills);
skillsWithWorkCenterDept.removeIf(skill -> !workCenterDepartments.contains(skill.getDepartment()));

Upvotes: 1

Michael
Michael

Reputation: 44150

First stream over the workCenters and get the set of departments in there, then stream over the skills and filter out any ones not present in that set.

final Set<String> workCenterDepartments = workCenters.stream()
    .map(B::getDepartment)
    .collect(Collectors.toSet());

final List<A> skillsWithWorkCenterDept = skills.stream()
    .filter(skill -> workCenterDepartments.contains(skill.getDepartment()))
    .collect(Collectors.toList());

If you don't need the old list any more, you might decide to remove elements from the previous list rather than create a new one:

skills.removeIf(skill -> !workCenterDepartments.contains(skill.getDepartment()));

Upvotes: 5

ernest_k
ernest_k

Reputation: 45319

You could start with converting HashSet<B> to HashSet<String> and then use your code:

Set<String> bDeps = workCenters.stream()
                               .map(B::getDepartment)
                               .collect(Collectors.toSet());

List<A> collect = skills.stream()
                         .filter(s -> bDeps.contains(s.getDepartment()))
                         .collect(Collectors.toList());

Upvotes: 6

Naman
Naman

Reputation: 31878

  1. collect all the department in workCenters into a Set<String>let's say departmentSet.
  2. List<A> collect = skills.stream()
                            .filter(s -> departmentSet.contains(s.getDepartment())
                            .collect(Collectors.toList());
    

Upvotes: 6

Related Questions