Java 8流是否与RxJava observables类似?
Java 8流定义:
新
java.util.stream
包中的类提供了一个Stream API 支持元素流上的功能样式操作。
答案 0 :(得分:131)
TL; DR :所有序列/流处理库都为管道构建提供了非常相似的API。不同之处在于用于处理多线程和管道组合的API。
RxJava与Stream完全不同。在所有JDK事物中,最接近rx.Observable的可能是 java.util.stream.Collector Stream + CompletableFuture组合(其代价是处理额外的monad层,即必须处理之间的转换) Stream<CompletableFuture<T>>
和CompletableFuture<Stream<T>>
)。
Observable和Stream之间存在显着差异:
Stream#parallel()
将序列拆分为分区,Observable#subscribeOn()
和Observable#observeOn()
不分区;使用Observable模拟Stream#parallel()
行为很棘手,它曾经有.parallel()
方法,但是这种方法造成了很多混乱,以至于.parallel()
支持被移动到github上的独立存储库RxJavaParallel。更多详情请见another answer。Stream#parallel()
不允许指定要使用的线程池,这与大多数接受可选Scheduler的RxJava方法不同。由于 JVM中的所有流实例使用相同的fork-join池,因此添加.parallel()
可能会意外影响程序的另一个模块中的行为Observable#interval()
,Observable#window()
和其他许多操作;这主要是因为Streams是基于拉力的takeWhile()
,takeUntil()
);使用Stream#anyMatch()
的变通方法是有限的:它是终端操作,因此您无法在每个流中使用它Observable#using()
);你可以用它包装IO流或互斥,并确保用户不会忘记释放资源 - 它将在订阅终止时自动处理; Stream有onClose(Runnable)
方法,但您必须手动或通过try-with-resources调用它。 E. g。你必须记住,文件#lines()必须包含在try-with-resources块中。综述:RxJava与Streams显着不同。 Real RxJava替代品是ReactiveStreams的其他实现,e。 G。阿卡的相关部分。
<强>更新即可。为Stream#parallel
使用非默认的fork-join池有诀窍,请参阅Custom thread pool in Java 8 parallel stream
<强>更新即可。以上所有内容均基于RxJava 1.x的经验。现在RxJava 2.x is here,这个答案可能已经过时了。
答案 1 :(得分:46)
Java 8 Stream和RxJava看起来非常相似。它们具有相似的运算符(filter,map,flatMap ......),但不是为相同的用法而构建的。
您可以使用RxJava执行asynchonus任务。
使用Java 8流,您将遍历集合中的项目。
你可以在RxJava(遍历集合的项目)中做同样的事情,但是,由于RxJava专注于并发任务,...,它使用同步,锁存,......所以使用RxJava的相同任务可能比Java 8流慢。
可以将RxJava与CompletableFuture
进行比较,但这样可以计算的不仅仅是一个值。
答案 2 :(得分:35)
存在一些技术和概念上的差异,例如,Java 8流是单用的,基于拉的,同步的值序列,而RxJava Observable是可重新观察的,基于自适应推送的,可能是异步的值序列。 RxJava针对Java 6+,也适用于Android。
答案 3 :(得分:29)
Java 8 Streams是基于拉取的。您遍历消耗每个项目的Java 8流。它可能是无穷无尽的。
RXJava Observable
默认是基于推送的。您订阅了Observable,当下一个项目到达时(onNext
),或者流完成(onCompleted
)或发生错误(onError
)时,您将收到通知。
因为Observable
您收到了onNext
,onCompleted
,onError
个事件,所以您可以执行一些强大的功能,例如将不同的Observable
组合到新的zip
中merge
1}},concat
,before do
VCR.turn_off!
WebMock.allow_net_connect!
end
after do
VCR.turn_on!
WebMock.disable_net_connect!
end
)。你可以做的其他事情是缓存,节流,......
它在不同语言中使用或多或少相同的API(RxJava,C#中的RX,RxJS,......)
默认情况下,RxJava是单线程的。除非您开始使用Scheduler,否则一切都将在同一个线程上发生。
答案 4 :(得分:22)
现有的答案是全面和正确的,但缺乏明确的初学者榜样。请允许我在“推/拉”和“可重新观察”等术语背后加上一些具体内容。 注意:我讨厌Observable
这个词(这是为了天堂的缘故),所以只会引用J8与RX流。
考虑一个整数列表,
digits = [1,2,3,4,5]
J8 Stream是一个用于修改集合的实用程序。例如,偶数可以被提取为,
evens = digits.stream().filter(x -> x%2).collect(Collectors.toList())
这基本上是Python的map, filter, reduce,这是Java的一个非常好的(并且早就应该)了。但是如果没有提前收集数字怎么办 - 如果数字在应用程序运行时流入,那么我们可以实时过滤偶数。
想象一下,一个单独的线程进程在应用程序运行时随机输出整数(---
表示时间)
digits = 12345---6------7--8--9-10--------11--12
在RX中,even
可以对每个新数字做出反应并实时应用过滤器
even = -2-4-----6---------8----10------------12
无需存储输入和输出列表。如果您想要输出列表,那么也没有问题可以流式传输。事实上,everything is a stream.
evens_stored = even.collect()
这就是“无状态”和“功能”等术语与RX
更相关的原因答案 5 :(得分:4)
RxJava也与reactive streams initiative密切相关,并将其视为反应流API的简单实现(例如与Akka streams implementation相比)。主要区别在于,反应流设计为能够处理背压,但如果您查看反应流页面,您将会得到这个想法。他们很好地描述了他们的目标,并且流也与the reactive manifesto密切相关。
Java 8流几乎是无界集合的实现,非常类似于Scala Stream或Clojure lazy seq。
答案 6 :(得分:2)
Java 8 Streams可以有效地处理真正大型的集合,同时利用多核架构。相比之下,RxJava默认是单线程的(没有Schedulers)。所以除非你自己编写逻辑,否则RxJava不会利用多核机器。