第一() 和采取(1) 之间的区别

2022-09-01 06:06:31

我正试图了解的细节。RxJava

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

这里有什么好处?还不能保证输出单个项目?single()take(1)


答案 1

不同之处在于,它将从上游中继 0..1 项,而将中继第一个元素,或者在上游为空时发出错误 (NoSuchElementException)。他们都没有阻止。take(1)first

将上游项目的数量限制为 1 并确保上游项目不为空,这是事实。first == take(1).single()take(1)single()

此示例仅打印“完成”

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

此示例打印“1”,后跟“完成”:

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

此示例还打印“1”,后跟“完成”:

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

此示例失败,因为NoSuchElementException

Observable.empty().first()
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));

此示例再次打印“1”,后跟“完成”:

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

此示例再次打印“1”,后跟“完成”:

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

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

Observable.empty().single()
.subscribe(System.out::println, 
    Throwable::printStackTrace, 
    () -> System.out.println("Done"));

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

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

答案 2

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

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

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

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

也有可能(同样,无需在引擎盖下查看以获得技术答案),这两种实现可能会以非常不同的方式处理错误条件。我个人希望为空集合抛出一个异常,因为没有第一个元素。但是,如果初始集合的元素少于,我可能会合理地期望返回小于 大小的集合,而不会出错。这可能会导致在给定空集合时返回空集合,而不会出错。first()take(x)xx

此外,作为一个技术问题,类似的东西更有可能不是立即实际迭代基础集合,而是推迟到某些东西迭代其结果。但是,需要迭代和具体化基础集合的第一个元素。take(x)first()


推荐