在 Java 中,流相对于循环的优势是什么? [英] In Java, what are the advantages of streams over loops?

查看:33
本文介绍了在 Java 中,流相对于循环的优势是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was asked this at an interview and I'm not convinced I gave the best answer I could have. I mentioned that you can do a parallel search and that null values were handled by some means I couldn't remember. Now I realize I was thinking of Optionals. What am I missing here? They claim it's better or more concise code but I'm not sure I agree.

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

Considering how succinctly it was answered, it seems that this wasn't too broad a question after all.

如果他们在面试中问这个问题,而且很明显他们是,那么除了让他们更难找到答案之外,分解它还有什么目的?我的意思是,你在找什么?我可以分解问题并回答所有子问题,然后创建一个带有所有子问题链接的父问题......虽然看起来很愚蠢.在此期间,请给我举一个不那么宽泛的问题的例子.我知道没有办法只问这个问题的一部分并且仍然得到有意义的答案.我可以用不同的方式问完全相同的问题.例如,我可以问流服务的目的是什么?"或我什么时候会使用流而不是 for 循环?"或者为什么要使用流而不是 for 循环?"这些都是完全相同的问题.

If they are asking this question at interviews, and clearly they are, what purpose could breaking it down serve other than to make it harder to find an answer? I mean, what are you looking for? I could break down the question and have all the sub-questions answered but then create a parent question with links to all the subquestions... seems pretty silly though. While we are at it, please give me an example of a less broad question. I know of no way to ask only part of this question and still get a meaningful answer. I could ask exactly the same question in a different way. For example, I could ask "What purpose do streams serve?" or "When would I use a stream instead of a for loop?" or "Why bother with streams instead of for loops?" These are all exactly the same question though.

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

...or is it considered too broad because someone gave a really long multi-point answer? Frankly anyone in the know could do that with virtually any question. If you happen to be one of the authors of the JVM, for example, you could probably talk about for loops all day long when most of us couldn't.

请编辑问题以将其限制为具有足够详细信息的特定问题,以确定适当的答案.避免同时提出多个不同的问题.请参阅如何提问页面以帮助澄清此问题."

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

As noted below, an adequate answer has been given which proves that there is one and that it is easy enough to provide.

推荐答案

有趣的是面试问题问的是优点,而不是问缺点,因为两者都有.

Interesting that the interview question asks about the advantages, without asking about disadvantages, for there are are both.

流是一种更具声明性的风格.或者更具表现力的风格.在代码中声明你的意图可能被认为比描述它是如何完成的更好:

Streams are a more declarative style. Or a more expressive style. It may be considered better to declare your intent in code, than to describe how it's done:

 return people
     .filter( p -> p.age() < 19)
     .collect(toList());

... 清楚地表明您正在从列表中过滤匹配元素,而:

... says quite clearly that you're filtering matching elements from a list, whereas:

 List<Person> filtered = new ArrayList<>();
 for(Person p : people) {
     if(p.age() < 19) {
         filtered.add(p);
     }
 }
 return filtered;

说我在做一个循环".循环的目的更深地埋藏在逻辑中.

Says "I'm doing a loop". The purpose of the loop is buried deeper in the logic.

流通常更简洁.同一个例子说明了这一点.简洁并不总是更好,但如果您能同时简洁和富有表现力,那就更好了.

Streams are often terser. The same example shows this. Terser isn't always better, but if you can be terse and expressive at the same time, so much the better.

流与函数有很强的亲和力.Java 8 引入了 lambda 表达式和函数式接口,这打开了一个包含强大技术的完整玩具箱.流提供了将函数应用于对象序列的最方便、最自然的方式.

Streams have a strong affinity with functions. Java 8 introduces lambdas and functional interfaces, which opens a whole toybox of powerful techniques. Streams provide the most convenient and natural way to apply functions to sequences of objects.

流鼓励减少可变性.这有点与函数式编程方面有关——您使用流编写的程序类型往往是您不修改对象的程序类型.

Streams encourage less mutability. This is sort of related to the functional programming aspect -- the kind of programs you write using streams tend to be the kind of programs where you don't modify objects.

流鼓励松散耦合.您的流处理代码不需要知道流的来源或其最终终止方法.

Streams encourage looser coupling. Your stream-handling code doesn't need to know the source of the stream, or its eventual terminating method.

流可以简洁地表达非常复杂的行为.例如:

 stream.filter(myfilter).findFirst();

乍一看好像它过滤了整个流,然后返回第一个元素.但实际上 findFirst() 驱动了整个操作,因此它在找到一项后有效地停止.

Might look at first glance as if it filters the whole stream, then returns the first element. But in fact findFirst() drives the whole operation, so it efficiently stops after finding one item.

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

Streams provide scope for future efficiency gains. Some people have benchmarked and found that single-threaded streams from in-memory Lists or arrays can be slower than the equivalent loop. This is plausible because there are more objects and overheads in play.

但流规模.除了 Java 对并行流操作的内置支持之外,还有一些使用 Streams 作为 API 的分布式 map-reduce 库,因为模型适合.

But streams scale. As well as Java's built-in support for parallel stream operations, there are a few libraries for distributed map-reduce using Streams as the API, because the model fits.

缺点?

性能:for 循环遍历数组在堆和 CPU 使用方面都非常轻量级.如果原始速度和内存节俭是优先事项,则使用流会更糟.

Performance: A for loop through an array is extremely lightweight both in terms of heap and CPU usage. If raw speed and memory thriftiness is a priority, using a stream is worse.

熟悉.世界上到处都是经验丰富的程序程序员,他们来自不同的语言背景,对他们来说循环很熟悉,流很新颖.在某些环境中,您希望编写这类人熟悉的代码.

Familiarity.The world is full of experienced procedural programmers, from many language backgrounds, for whom loops are familiar and streams are novel. In some environments, you want to write code that's familiar to that kind of person.

认知开销.由于它的声明性质,以及对底层发生的事情的更多抽象,您可能需要构建一个新的代码与执行相关的思维模型.实际上,您只需要在出现问题时,或者需要深入分析性能或细微错误时才需要这样做.当它正常工作"时,它就会正常工作.

Cognitive overhead. Because of its declarative nature, and increased abstraction from what's happening underneath, you may need to build a new mental model of how code relates to execution. Actually you only need to do this when things go wrong, or if you need to deeply analyse performance or subtle bugs. When it "just works", it just works.

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

Debuggers are improving, but even now, when you're stepping through stream code in a debugger, it can be harder work than the equivalent loop, because a simple loop is very close to the variables and code locations that a traditional debugger works with.

这篇关于在 Java 中,流相对于循环的优势是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆