繁体   English   中英

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

[英]Based on condition set object value and return boolean using java 8 streams

如果条件为真,我有嵌套列表,并且能够设置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作为可变的“盒子”来解决无法突变捕获的局部变量的问题。 它也比单元素数组技巧更好,因为如果并行运行流,原子是安全的。

这也使用了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<Department> 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 ,它的效率有所降低,但从代码可读性的角度来看,它比其他建议的变体更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM