Java 中stream比普通的循环好在哪儿呢?

->>>>文章源地址<<<<<-

原问题:

In Java, what are the advantages of streams over loops?

Java 中stream比普通的循环好在哪儿呢?

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中筛选元素,但是下面这段代码:

 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.

stream 风格 总体上来说是简洁,上边的例子印证了。当然简洁也不总是最好的,但是如果你可以同时保持简洁和容易理解,那么何乐而不为呢?

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.

stream 跟函数有很强的兼容性,Java8 引入的 lambdas 表达式函数式接口 是带来了一些非常有用的新玩意儿。stream
提供最方便最自然的方式来 实现 一串对象序列的函数操作。

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.

stream 鼓励低可变性。这里就涉及到了函数式编程–你用stream写出的程序这种程序往往是不会改变其内在对象的。

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

stream 鼓励低耦合。你的stream中的处理代码不需要去了解stream的来源,以及它的最终结束方法。(没彻底理解)

Streams can succinctly express quite sophisticated behaviour. For example:

stream可以简洁的表达出相当复杂的行为。举个例子:

stream.filter(myfilter).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.

这段代码一打眼看起来像是筛选了整个流,然后返回第一个符合的元素,但是事实上
*findFirst()*影响着整个操作,所以当找到第一个符合的元素之后,它就会直接停止处理。

**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.
**

stream 放眼于 未来效率的收益(我猜测是指 后期代码的维护等等…)有些朋友做过测评,发现单线程的stream 处理Lists 或者
arrays 的时候比普通的循环慢些,这是理所当然的,因为这里边有很多对象需要创建以及很多其他的处理流程。

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.

但是 stream 的规模,以及Java 对并行stream 内置操作,有一些分布式 map-reduce 库就把stream
作为API,因为模型合适。

Disadvantages?

缺点呢?

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.

1.性能方面:普通循环对array的操作 对于 堆内存 和 cpu的占用 都是很轻量级的,如果速度快和低内存占用是你的首选,那么建议不要用stream。

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.

2.不眼熟:世界上有很多经验丰富的开发者,有过多种语言的开发背景,他们都熟悉普通的循环,stream对他们来说是比较新的东西,一些情况下,你需要写出和他们一样的代码。

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.

3.有点学习成本:由于它是倾向于行为展示的(stream 风格 代码展示出它做了什么而不是它是如何做的),对底层如何实现进一步抽象化,你可能需要学习一种关于代码和执行结果的新的思维模型。其实你只需要在代码出错后或者你想分析一些很细小的Bug再这样做,因为如果你没出错,那你的思维模式就是对的,当你的思维模式是对的的时候那么你就对了,没必要再重新创建模型了。

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.

4:调试有点困难:调试器正在进一步开发,但是即使是现在,当你debug步入stream中的代码时,它几乎不能debug到对应地方,但是普通的循环可以很简单的定位到,因为一个普通循环中
变量和代码位置联系比较紧密,调试器可以很容易定位到。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值