Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于条件集对象值并使用Java8流返回布尔值_Java_Java 8_Java Stream - Fatal编程技术网

基于条件集对象值并使用Java8流返回布尔值

基于条件集对象值并使用Java8流返回布尔值,java,java-8,java-stream,Java,Java 8,Java Stream,我有嵌套列表,并且能够在条件为真时设置isMatched和department.setMatchedStatus(真) boolean isMatched = false; for (Employee employee: company.getEmployees()) { for (Department department: employee.getDepartments()) { if(departmentList.contains(department.getDep

我有嵌套列表,并且能够在条件为真时设置isMatched和department.setMatchedStatus(真)

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;
我想使用Java8流实现同样的功能,我尝试使用下面的代码,但无法返回布尔值

 isMatched = company.getEmployees().stream()
.flatMap(employee-> employee.getDepartments().stream())
.filter((department) -> departmentList.contains(department.getDepartmentName()))
.forEach((department) -> department.setMatchedStatus(true));
有人能帮我吗?

您可以在流上使用“peek()”方法,它允许您在不改变流内容的情况下使用流中的项目。更新每个对象后,只需知道是否有匹配的对象

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

这里的困难在于您需要执行两个副作用:设置
部门
对象上的匹配状态,以及设置本地标志值以确定是否存在任何匹配。在中使用
peek
count
的方法将起作用,因为在这种情况下,我们可以确保
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();

对我来说,最明确的解决办法是:

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();
设置匹配部门=
company.getEmployees().stream()
.flatMap(employee->employee.getDepartments().stream())
.filter(department->departmentList.contains(department.getDepartmentName()))
.collect(收集器.toSet());
matchingDepartments.forEach(department->department.setMatchedStatus(true));
回来!匹配部门。i空();

在生成中间
集时,它的效率稍低,但从代码可读性的角度来看,它比其他建议的变体要好。

您的原始代码也不会返回bool。您只需设置属性,stream()代码也会这样做。很抱歉,实际上我错过了它,我将只进行编辑。编辑-count()
应该使用流。它可能会,但不能保证它会。我模模糊糊地记得关于基于数组的流优化等的讨论,我将试图找到一些相关信息。Javadoc说
count()
相当于
return-mapToLong(e->1L).sum()和是一个减少操作。似乎它应该消耗整个流。@绿巨人,在这种特殊情况下它仍然有效,因为存在
flatMap
filter
流大小事先未知。但是,这种代码风格(即使用
peek
进行非调试)肯定是不好的。流中任何对象的变化在某个时候都会有问题。流并不是真正为有状态对象的变化而设计或优化的。如果对象模型是不可变的,那么流的使用可能会更干净、更习惯。