Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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
在Java中,流比循环有什么优势?_Java_Loops_Java 8_Java Stream - Fatal编程技术网

在Java中,流比循环有什么优势?

在Java中,流比循环有什么优势?,java,loops,java-8,java-stream,Java,Loops,Java 8,Java Stream,我在一次采访中被问到这个问题,我不相信我给出了最好的答案。我提到可以进行并行搜索,空值是通过一些我不记得的方法处理的。现在我意识到我在考虑选择。我错过了什么?他们声称这是更好或更简洁的代码,但我不确定我是否同意 考虑到它的回答是多么简洁,这似乎毕竟不是一个太宽泛的问题 如果他们在面试时问这个问题,很明显他们是这样问的,那么把问题分解除了让问题更难找到答案之外,还有什么用呢?我是说,你在找什么?我可以将问题分解并回答所有的子问题,然后创建一个带有所有子问题链接的家长问题。。。不过看起来很傻。在

我在一次采访中被问到这个问题,我不相信我给出了最好的答案。我提到可以进行并行搜索,空值是通过一些我不记得的方法处理的。现在我意识到我在考虑选择。我错过了什么?他们声称这是更好或更简洁的代码,但我不确定我是否同意


考虑到它的回答是多么简洁,这似乎毕竟不是一个太宽泛的问题


如果他们在面试时问这个问题,很明显他们是这样问的,那么把问题分解除了让问题更难找到答案之外,还有什么用呢?我是说,你在找什么?我可以将问题分解并回答所有的子问题,然后创建一个带有所有子问题链接的家长问题。。。不过看起来很傻。在我们讨论这个问题时,请给我举一个不太宽泛的问题的例子。我知道没有办法只问这个问题的一部分,而仍然得到一个有意义的答案。我可以用不同的方式问完全相同的问题。例如,我可以问“流的用途是什么?”或者“我什么时候用流代替For循环?”或者“为什么要用流代替For循环?”这些都是完全相同的问题

……还是因为有人给出了一个很长的多点答案而被认为过于宽泛?坦率地说,任何有知识的人都可以用几乎任何问题做到这一点。例如,如果您碰巧是JVM的作者之一,您可能会整天谈论for循环,而我们大多数人却不能

“请编辑该问题,将其限制为特定问题,并提供足够的详细信息,以确定适当的答案。避免一次提出多个不同的问题。请参阅“如何提问”页面以获取澄清此问题的帮助。”

如下文所述,已经给出了一个充分的答案,证明有一个答案,而且很容易提供

  • 您没有正确认识到:并行操作使用
    s,而不是
    可选
    s

  • 您可以定义使用流的方法:将它们作为参数,返回它们,等等。您不能定义将循环作为参数的方法。这允许一次复杂的流操作并多次使用它。请注意,Java在这里有一个缺点:您的方法必须被称为
    someMethod(stream)
    ,而不是stream自己的
    stream.someMethod()
    ,因此混合使用它们会使阅读变得复杂:试着在

    myMethod2(myMethod(stream.transform(...)).filter(...))
    
    许多其他语言(C#、Kotlin、Scala等)允许某种形式的“扩展方法”

  • 即使您只需要顺序操作,并且不想重用它们,以便可以使用流或循环,流上的简单操作也可能对应于循环中相当复杂的更改

  • 您在序列(数组、集合、输入等)上循环,因为您希望对序列的元素应用某些函数

    流使您能够在序列元素上组合函数,并允许独立于具体案例实施最常见的函数(例如映射、过滤、查找、排序、收集等)


    因此,在大多数情况下,给定一些循环任务,您可以使用较少的代码使用流来表达它,也就是说,您获得了可读性

    有趣的是,面试问题询问了优点,而没有问缺点,因为两者都有

    流是一种更具声明性的样式。或者更具表现力的风格。在代码中声明您的意图可能比描述它是如何完成的要好:

     return people
         .filter( p -> p.age() < 19)
         .collect(toList());
    
    乍一看似乎它过滤了整个流,然后返回第一个元素。但事实上,
    findFirst()
    驱动整个操作,因此它在找到一个项目后会有效地停止

    数据流为未来的效率提升提供了空间。一些人进行了基准测试,发现内存
    List
    s或数组中的单线程流可能比等效循环慢。这是合理的,因为有更多的对象和间接费用在发挥作用

    但溪流规模很大。除了Java内置的对并行流操作的支持外,还有一些使用流作为API的分布式map reduce库,因为该模型非常适合

    缺点?

    性能:通过数组的
    循环在堆和CPU使用方面都非常轻量级。如果优先考虑原始速度和内存节约,那么使用流就更糟

    熟悉性。世界上到处都是经验丰富的程序程序员,他们来自许多语言背景,对他们来说循环是熟悉的,流是新奇的。在某些环境中,您希望编写这种人熟悉的代码

    认知开销。由于它的声明性性质,以及从底层发生的事情中增加的抽象性,您可能需要构建一个新的思维模型来描述代码与执行之间的关系。实际上,您只需要在出现问题时,或者需要深入分析性能或细微缺陷时,才需要这样做。当它“起作用”时,它就起作用了


    调试器正在改进,但即使是现在,当您在调试器中单步执行流代码时,也可能比等效循环更困难,因为简单循环非常接近传统调试器使用的变量和代码位置。

    语法乐趣除外,流被设计用于处理可能无限大的数据集,而数组、集合和几乎所有实现Iterable的JavaSE类都完全在内存中

    流的一个缺点是过滤器、映射等不能抛出已检查的异常。这使得一条流成为一个糟糕的选择
     List<Person> filtered = new ArrayList<>();
     for(Person p : people) {
         if(p.age() < 19) {
             filtered.add(p);
         }
     }
     return filtered;
    
     stream.filter(myfilter).findFirst();