2015-11-19 102 views
2

我是新来的Java 8和Stream API。Java 8集合 - 在嵌套列表中过滤值

如果我有Employee对象的列表:

List<Employee> employees; 

public class Employee { 
    private String name; 
    private List<Project> involvedInProjects; 
} 

public class Project { 
    private int projectId; 
} 

我想在beeing参与某些项目的员工进行筛选,我将如何去在Java 8与流API这样做呢?

如果我有一个Map,其中的密钥是唯一的employeeID而不是List,会更容易吗?

+0

我同意这是一个不正确的标题。我现在编辑它。但我不同意它缺乏实际的编程问题。也许我有点不清楚;所以我删除了“例如,如果我想”。感谢您的更正。 – sjallamander

回答

2

如果您不介意修改列表,您可以使用removeIf以及您将提供的谓词作为参数,以检查员工涉及的项目是否与给定ID不匹配。

例如,

employees.removeIf(e -> e.getInvolvedInProjects().stream().anyMatch(p -> p.getProjectId() == someId)); 

如果列表不支持消除元件,从employees列表抢流,并与对面的谓词(在这种情况下,你可以使用.noneMatch(p -> p.getProjectId() == someId))过滤它作为removeIf并使用Collectors.toList()收集结果。

+1

使用流和过滤器时,需要与'removeIf'中相同的*谓词。除此之外,最好首先获取实际的'Project'实例并做一个简单的'getInvolvedInProjects().contains(project)'测试(假设'Project's是规范的或者有一个合适的'equals'方法,否则将是一个值得怀疑的设计)... – Holger

+1

@Holger谢谢,今天不知道我的错在哪里!完全同意你的最后一点... –

3

所以你可以访问流操作中的嵌套列表,然后使用它。在这种情况下,我们可以使用嵌套流作为我们断言对于过滤

employees.stream().filter(
employee -> employee.involvedInProjects.stream() 
.anyMatch(proj -> proj.projectId == myTargetId)) 

这会给你所有具有至少一个项目匹配你目标ID员工的流。从这里你可以进一步操作流或收集流与列表.collect(Collectors.toList())