Java 8 流懒惰在实践中是无用的吗?
我最近阅读了很多关于Java 8流的文章,以及几篇关于使用Java 8流延迟加载的文章:这里和这里。我似乎无法摆脱延迟加载完全无用的感觉(或者充其量,一个提供零性能值的次要语法便利)。
让我们以这段代码为例:
int[] myInts = new int[]{1,2,3,5,8,13,21};
IntStream myIntStream = IntStream.of(myInts);
int[] myChangedArray = myIntStream
.peek(n -> System.out.println("About to square: " + n))
.map(n -> (int)Math.pow(n, 2))
.peek(n -> System.out.println("Done squaring, result: " + n))
.toArray();
这将登录到控制台中,因为 在这种情况下,将调用 ,并且我们的流是惰性的,并且仅在调用终端操作时执行。当然,我也可以这样做:terminal operation
toArray()
IntStream myChangedInts = myIntStream
.peek(n -> System.out.println("About to square: " + n))
.map(n -> (int)Math.pow(n, 2))
.peek(n -> System.out.println("Done squaring, result: " + n));
什么都不会打印出来,因为地图没有发生,因为我不需要数据。直到我称之为:
int[] myChangedArray = myChangedInts.toArray();
瞧,我得到了我的映射数据,以及我的控制台日志。除了我看不到任何好处。我意识到我可以在调用之前很久就定义过滤器代码,并且我可以传递这个“不是真正过滤的流”),但那又如何呢?这是唯一的好处吗?toArray()
这些文章似乎暗示懒惰会带来性能提升,例如:
在Java 8 Streams API中,中间操作是懒惰的,并且其内部处理模型经过优化,使其能够以高性能处理大量数据。
和
Java 8 Streams API 在短路操作的帮助下优化了流处理。短路方法在满足其条件后立即结束流处理。用正常的话说,短路操作,一旦条件得到满足,就打破了所有的中间操作,躺在管道里。某些中间操作以及终端操作具有此行为。
这听起来就像打破了一个循环,与懒惰无关。
最后,第二篇文章中有这样一句令人困惑的话:
惰性操作可提高效率。这是一种不处理陈旧数据的方法。在逐步消耗输入数据而不是事先拥有整个完整元素集的情况下,惰性操作可能很有用。例如,考虑使用 Stream#generate(Supplier<T>) 创建无限流的情况,并且提供的 Supplier 函数正在逐渐从远程服务器接收数据。在这些情况下,服务器调用将仅在需要时在终端操作时进行。
不处理陈旧数据?什么?延迟加载如何防止某人处理过时的数据?
TLDR:除了能够在以后运行过滤器/映射/减少/任何操作(这不会提供任何性能好处)之外,延迟加载还有什么好处?
如果是这样,什么是现实世界的用例?