基于条件设置对象值并使用java 8流返回布尔值

我有嵌套列表,如果条件为真,我可以设置isMatched和department.setMatchedStatus(true)。

boolean isMatched = false; for (Employee employee: company.getEmployees()) { for (Department department: employee.getDepartments()) { if(departmentList.contains(department.getDepartmentName())){ isMatched = true; department.setMatchedStatus(true); } } } return isMatched; 

想使用java 8流实现相同,我尝试使用下面的代码,但无法返回布尔值。

  isMatched = company.getEmployees().stream() .flatMap(employee-> employee.getDepartments().stream()) .filter((department) -> departmentList.contains(department.getDepartmentName())) .forEach((department) -> department.setMatchedStatus(true)); 

有人可以帮我吗?

这里的难点在于您有两个需要执行的副作用:在Department对象上设置匹配状态,并设置本地标志值以确定是否存在任何匹配。 在sisyphus的回答中使用peekcount的方法是有效的,因为在这种情况下我们可以确保count不会短路。 但是,它可能会导致维护问题。 如果有人复制并重新安排这些代码,它可能会因为短路而无声地中断,这将是非常微妙的。

也许更好的方法是将副作用打包到forEach操作中。 这使用AtomicBoolean作为可变“框”来解决无法改变捕获的局部变量的问题。 它也优于单元素数组技巧,因为在并行运行流时,primefaces是安全的。

这也使用了一个语句lambda,我通常宁愿避免。 在这种情况下,它并不太糟糕,并且表明正在发生多种副作用。

  AtomicBoolean isMatched = new AtomicBoolean(false); company.getEmployees().stream() .flatMap(employee -> employee.getDepartments().stream()) .filter(department -> departmentList.contains(department.getDepartmentName())) .forEach(department -> { department.setMatchedStatus(true); isMatched.set(true); }); return isMatched.get(); 

您可以在Stream上使用’peek()’方法,它允许您使用流中的项而不更改流的内容。 更新每个对象后,您只需要知道是否匹配。

 return company.getEmployees().stream() .flatMap(employee-> employee.getDepartments().stream()) .filter((department) -> departmentList.contains(department.getDepartmentName())) .peek((department) -> department.setMatchedStatus(true)) .count() > 0; 

对我来说,最明确的解决方案如下:

 Set matchingDepartments = company.getEmployees().stream() .flatMap(employee -> employee.getDepartments().stream()) .filter(department -> departmentList.contains(department.getDepartmentName())) .collect(Collectors.toSet()); matchingDepartments.forEach(department -> department.setMatchedStatus(true)); return !matchingDepartments.isEmpty(); 

它产生一个中间Set效率稍低,但从代码可读性的角度来看,它看起来比其他提出的变体更好。