pau*_*aul 4 java optional java-8 java-stream
我正在使用Stream过滤器findAny.orElse,但它没有像我期望的那样工作,所以我认为我不理解它是如何工作的.在这里我的代码
return Stream.of(getObjectAttributeValue(product, matchCriteria.getFieldName()))
.map(o -> isIngredientRestricted(matchCriteria, (List<String>) o))
.filter(Boolean::valueOf)
.findAny().orElse(isCommercialHierarchyInfoRestricted(product, matchCriteria));
Run Code Online (Sandbox Code Playgroud)
基本上我所期望的是,如果第一个地图发出布尔值false,那么它将被过滤,因此findAny将找不到任何可选项,因此将调用orElse.但即使在过滤器中有一个true,也会调用isCommercialHierarchyInfoRestricted.
知道我做错了什么吗?
你实际上需要使用orElseGet:
.findAny().orElseGet(() -> isCommercialHierarchyInfoRestricted(product, matchCriteria));
Run Code Online (Sandbox Code Playgroud)
在Java方法中,始终在方法调用之前计算参数,即使在方法内部不必要,因此您无法避免评估orElse参数.这就是orElseGet存在的原因:它的参数是函数,并且在没有必要时根本不执行函数.
正如Tagir所解释的那样,使用orElse(expression)始终会expression在调用方法之前进行评估,orElse而您必须使用它orElseGet(() -> expression)来推迟对表达式的求值.
但是,这是StreamAPI 的不必要使用.如果要评估单个项目,则不需要创建单个元素流,只是为了findAny之后调用.你可以Optional在第一时间创建一个:
return Optional.of(getObjectAttributeValue(product, matchCriteria.getFieldName()))
.map(o -> isIngredientRestricted(matchCriteria, (List<String>)o))
.filter(b -> b)
.orElseGet(() -> isCommercialHierarchyInfoRestricted(product, matchCriteria));
Run Code Online (Sandbox Code Playgroud)
但是,与同等的普通Java语言构造相比,即使这是一个不必要的复杂问题:
return isIngredientRestricted(matchCriteria,
(List<String>)getObjectAttributeValue(product, matchCriteria.getFieldName()))
|| isCommercialHierarchyInfoRestricted(product, matchCriteria);
Run Code Online (Sandbox Code Playgroud)
这完全相同,无需额外的API或lambda表达式.该||运营商还保证了第二个表达式将不会得到评估,如果第一个计算结果为true.
| 归档时间: |
|
| 查看次数: |
14026 次 |
| 最近记录: |