gpt4 book ai didi

java - 为什么我不能将过滤器用作流中的最后一步

转载 作者:行者123 更新时间:2023-12-04 05:22:26 25 4
gpt4 key购买 nike

我一直被告知不通过 collect 和 findFirst 等方法终止 Stream 是不好的做法,但没有真正的反馈来说明为什么在博客中很少提及它。

看看下面的例子,我没有使用大量嵌套的 if 检查,而是使用 Optional 来取回 List 值。如您所见,我的最后一步是在该流中过滤。这对我来说按预期工作,即取回列表。为什么这是错误的,我应该如何写呢?

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
}

最佳答案

I keep getting told it is bad practice to not terminate a Stream via methods such as collect and findFirst but no real feedback as to why not much said about it in blogs.



这真的取决于 上下文 ,如果你说“我可以用中间操作结束一个流,例如 filter 并且不调用终端操作(消耗流的操作) 曾经 ”那么是的,这是不好的做法和种类毫无意义,因为您刚刚定义了一些标准,但从未要求过“结果”。

从某种意义上说,流是惰性的,除非终端操作告诉它们,否则它们不会做任何事情,例如 collect , findFirst等等。

如果您说“从方法返回流是不好的做法吗”,那么
是否值得阅读此答案 should return a stream or a collection .

此外,请注意您的 getBeanViaOptional逻辑正在 Optional<T> 上运行而不是 Stream<T> .是的,他们都有 map , flatMapfilter但请注意 Optional<T>只能包含 一个值 或者是 而一个流可以有一个或多个。

您使用 Optional 而不是命令式的方法 if s 在可读性、维护等方面明显更好,所以我建议你继续使用这种方法,尽管你可以使用 orElseThrow 稍微改进它。 IE。:
return 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)
.filter(n -> n.contains("apple"))
.orElseThrow(CustomException::new);

关于java - 为什么我不能将过滤器用作流中的最后一步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58039642/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com