java为什么我不能使用过滤器作为流中的最后一步
我一直被告知,不通过collect和findFirst等方法终止流是一种不好的做法,但没有真正的反馈来解释为什么博客上没有太多关于它的评论
看看下面的例子,我没有使用大量嵌套的if检查,而是使用Optional返回列表值。正如你们所看到的,我的最后一步是在那个流中过滤。这对我来说就像预期的一样,就是要得到一份清单。为什么这是错误的,我应该怎么写呢
import lombok.Getter;
import lombok.Setter;
import java.util.*;
public class Main {
public static void main(String[] args) {
RequestBean requestBean = new RequestBean();
// if I uncomment this I will get the list values printed as expected
// FruitBean fruitBean = new FruitBean();
// AnotherBean anotherBean = new AnotherBean();
// InnerBean innerBean = new InnerBean();
// requestBean.setFruitBeans(Collections.singletonList(fruitBean));
// fruitBean.setAnotherBeans(Collections.singletonList(anotherBean));
// anotherBean.setInnerBeans(Collections.singletonList(innerBean));
// List<String> beans = Arrays.asList("apple", "orange");
// innerBean.setBeans(beans);
List<String> result = getBeanViaOptional(requestBean);
if(result != null){
for(String s : result){
System.out.println(s);
}
}else {
System.out.println("nothing in list");
}
}
private static List<String> getBeanViaOptional(RequestBean bean){
Optional<List<String>> output = Optional.ofNullable(bean)
.map(RequestBean::getFruitBeans)
.map(n -> n.get(0))
.map(FruitBean::getAnotherBeans)
.map(n -> n.get(0))
.map(AnotherBean::getInnerBeans)
.map(n -> n.get(0))
.map(InnerBean::getBeans)
// why is this bad practice to end with a filter. how should I write this then?
.filter(n -> n.contains("apple"));
if(!output.isPresent()){
throw new CustomException();
}
return output.get();
}
// not using this. just to show that optional was preferable compared to this.
private static List<String> getBeanViaIfChecks(RequestBean bean){
if(bean != null){
if(bean.getFruitBeans() != null){
if(bean.getFruitBeans().get(0) != null){
if(bean.getFruitBeans().get(0).getAnotherBeans() != null){
if(bean.getFruitBeans().get(0).getAnotherBeans().get(0) != null){
if(bean.getFruitBeans().get(0).getAnotherBeans().get(0).getInnerBeans() != null){
if(bean.getFruitBeans().get(0).getAnotherBeans().get(0).getInnerBeans().get(0) != null){
return bean.getFruitBeans().get(0).getAnotherBeans().get(0).getInnerBeans().get(0).getBeans();
}
}
}
}
}
}
}
return null;
}
}
@Getter
@Setter
class RequestBean{
List<FruitBean> fruitBeans;
}
@Getter
@Setter
class FruitBean{
List<AnotherBean> anotherBeans;
}
@Getter
@Setter
class AnotherBean{
List<InnerBean> innerBeans;
}
@Getter
@Setter
class InnerBean{
List<String> beans;
}
class CustomException extends RuntimeException{
// do some custom exception stuff
}
# 1 楼答案
对于流,当没有终端操作时,通常不会执行任何中间操作。您的示例使用
Optional
。它的操作map
和filter
与流中的一些中间操作同名,但它们不同。在你的问题中,你的例子是正确的(不坏的做法)另一件事是(正如Aomine已经指出的)}。如果没有值,您将得到一个
.orElseThrow
是获取Optional
中的值并在没有异常时抛出异常的较短方法。更重要的是,使用.orElseThrow
更安全 (如果有默认值,则为.orElse
)^尽可能避免使用{NoSuchElementException
。这几乎和不使用Optional
时得到NullPointerException
一样糟糕Optional
正确使用可以保护您免受NullPointerException