有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    对于流,当没有终端操作时,通常不会执行任何中间操作。您的示例使用Optional。它的操作mapfilter与流中的一些中间操作同名,但它们不同。在你的问题中,你的例子是正确的(不坏的做法)

    另一件事是(正如Aomine已经指出的).orElseThrow是获取Optional中的值并在没有异常时抛出异常的较短方法。更重要的是,使用.orElseThrow更安全 (如果有默认值,则为.orElse)^尽可能避免使用{}。如果没有值,您将得到一个NoSuchElementException。这几乎和不使用Optional时得到NullPointerException一样糟糕Optional正确使用可以保护您免受NullPointerException