first()和take(1)之间的区别

Pau*_*hek 29 java reactive-programming rx-java

我想了解细节RxJava.

直觉上我期望first()并且take(1)平等并且做同样的事情.但是通过挖掘源代码first()定义为take(1).single().

这有什么single()用?还不take(1)保证输出单个项目吗?

aka*_*okd 37

区别在于,如果上游为空,take(1)将从上游中继0..1项,而first将中继第一个元素或发出错误(NoSuchElementException).它们都没有阻挡.

它是真实的first == take(1).single(),其中take(1)限制了上游项1的数量和single()确保上游不为空.

此示例仅打印"完成"

Observable.empty().take(1)
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));
Run Code Online (Sandbox Code Playgroud)

此示例打印"1"后跟"完成":

Observable.just(1).take(1)
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));
Run Code Online (Sandbox Code Playgroud)

此示例还打印"1"后跟"完成":

Observable.just(1, 2, 3).take(1)
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));
Run Code Online (Sandbox Code Playgroud)

这个例子失败了 NoSuchElementException

Observable.empty().first()
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));
Run Code Online (Sandbox Code Playgroud)

此示例再次打印"1"后跟"完成":

Observable.just(1).first()
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));
Run Code Online (Sandbox Code Playgroud)

此示例再次打印"1"后跟"完成":

Observable.just(1, 2, 3).first()
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));
Run Code Online (Sandbox Code Playgroud)

此示例打印堆栈跟踪,NoSuchElementException因为源包含的元素太少:

Observable.empty().single()
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));
Run Code Online (Sandbox Code Playgroud)

此示例打印堆栈跟踪,IllegalArgumentException因为源包含太多元素:

Observable.just(1, 2, 3).single()
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));
Run Code Online (Sandbox Code Playgroud)


Dav*_*vid 5

实现的差异是由语义的差异驱动的.如果不了解语言及其内部工作原理,请考虑这两种方法的含义.

first()意味着它将只返回一个元素.集合中的第一个元素.

take(x)意味着它将返回一组元素.x集合中的第一个元素.

不同的语义需要不同的名称.不同的返回值需要不同的技术实现.

这也是可能的(再次,无需深入了解技术答案),这两种实现可能会以非常不同的方式处理错误情况.我个人希望first()为空集合抛出异常,因为没有第一个元素.但是,如果初始集合的元素少于元素,我可能会合理地期望take(x)返回小于大小的集合x,而不会出现错误x.每当给出一个空集合时,这可能导致无错误地返回空集合.

另外,作为一个技术问题,类似的东西take(x)更有可能不会立即迭代底层集合,而是推迟到某些东西迭代其结果. first()但是,需要迭代并具体化底层集合的第一个元素.