diff --git a/docs/Operator-Matrix.md b/docs/Operator-Matrix.md
index a44eed94ec..cd71558ddb 100644
--- a/docs/Operator-Matrix.md
+++ b/docs/Operator-Matrix.md
@@ -37,102 +37,102 @@ Operator | |||| ([25](#notes-25))|
`concatDelayError`||||||
`concatEager`||||| ([26](#notes-26))|
-`concatMap`||||| ([27](#notes-27))|
-`concatMapCompletable`||||| ([27](#notes-27))|
+`concatMap`||||| ([27](#notes-27))|
+`concatMapCompletable`||||| ([27](#notes-27))|
`concatMapCompletableDelayError`||| ([28](#notes-28))| ([28](#notes-28))| ([27](#notes-27))|
`concatMapDelayError`||| ([29](#notes-29))| ([29](#notes-29))| ([27](#notes-27))|
-`concatMapEager`||||||
-`concatMapEagerDelayError`||||||
-`concatMapIterable`||| ([30](#notes-30))| ([30](#notes-30))| ([27](#notes-27))|
-`concatMapMaybe`||||| ([27](#notes-27))|
-`concatMapMaybeDelayError`||| ([31](#notes-31))| ([31](#notes-31))| ([27](#notes-27))|
-`concatMapSingle`||||| ([27](#notes-27))|
-`concatMapSingleDelayError`||| ([32](#notes-32))| ([32](#notes-32))| ([27](#notes-27))|
-`concatMapStream`||| ([33](#notes-33))| ([33](#notes-33))| ([27](#notes-27))|
+`concatMapEager`||| ([30](#notes-30))| ([30](#notes-30))| ([27](#notes-27))|
+`concatMapEagerDelayError`||| ([30](#notes-30))| ([30](#notes-30))| ([27](#notes-27))|
+`concatMapIterable`||| ([31](#notes-31))| ([31](#notes-31))| ([27](#notes-27))|
+`concatMapMaybe`||| ([32](#notes-32))|| ([27](#notes-27))|
+`concatMapMaybeDelayError`||| ([33](#notes-33))| ([33](#notes-33))| ([27](#notes-27))|
+`concatMapSingle`|||| ([34](#notes-34))| ([27](#notes-27))|
+`concatMapSingleDelayError`||| ([35](#notes-35))| ([35](#notes-35))| ([27](#notes-27))|
+`concatMapStream`||| ([36](#notes-36))| ([36](#notes-36))| ([27](#notes-27))|
`concatWith`||||||
`contains`||||| ([2](#notes-2))|
-`count`|||| ([34](#notes-34))| ([35](#notes-35))|
+`count`|||| ([37](#notes-37))| ([38](#notes-38))|
`create`||||||
-`debounce`||| ([36](#notes-36))| ([36](#notes-36))| ([37](#notes-37))|
-`defaultIfEmpty`|||| ([23](#notes-23))| ([38](#notes-38))|
+`debounce`||| ([39](#notes-39))| ([39](#notes-39))| ([40](#notes-40))|
+`defaultIfEmpty`|||| ([23](#notes-23))| ([41](#notes-41))|
`defer`||||||
`delay`||||||
`delaySubscription`||||||
-`dematerialize`||||| ([37](#notes-37))|
-`distinct`||| ([39](#notes-39))| ([39](#notes-39))| ([37](#notes-37))|
-`distinctUntilChanged`||| ([39](#notes-39))| ([39](#notes-39))| ([37](#notes-37))|
-`doAfterNext`||| ([40](#notes-40))| ([40](#notes-40))| ([2](#notes-2))|
-`doAfterSuccess`| ([41](#notes-41))| ([41](#notes-41))||| ([37](#notes-37))|
+`dematerialize`||||| ([40](#notes-40))|
+`distinct`||| ([42](#notes-42))| ([42](#notes-42))| ([40](#notes-40))|
+`distinctUntilChanged`||| ([42](#notes-42))| ([42](#notes-42))| ([40](#notes-40))|
+`doAfterNext`||| ([43](#notes-43))| ([43](#notes-43))| ([2](#notes-2))|
+`doAfterSuccess`| ([44](#notes-44))| ([44](#notes-44))||| ([40](#notes-40))|
`doAfterTerminate`||||||
`doFinally`||||||
-`doOnCancel`|| ([42](#notes-42))| ([42](#notes-42))| ([42](#notes-42))| ([42](#notes-42))|
-`doOnComplete`|||| ([43](#notes-43))||
-`doOnDispose`| ([44](#notes-44))|||||
-`doOnEach`||| ([45](#notes-45))| ([45](#notes-45))| ([37](#notes-37))|
+`doOnCancel`|| ([45](#notes-45))| ([45](#notes-45))| ([45](#notes-45))| ([45](#notes-45))|
+`doOnComplete`|||| ([46](#notes-46))||
+`doOnDispose`| ([47](#notes-47))|||||
+`doOnEach`||| ([48](#notes-48))| ([48](#notes-48))| ([40](#notes-40))|
`doOnError`||||||
-`doOnEvent`| ([46](#notes-46))| ([46](#notes-46))||||
+`doOnEvent`| ([49](#notes-49))| ([49](#notes-49))||||
`doOnLifecycle`||||||
-`doOnNext`||| ([47](#notes-47))| ([47](#notes-47))| ([37](#notes-37))|
-`doOnRequest`|| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))|
+`doOnNext`||| ([50](#notes-50))| ([50](#notes-50))| ([40](#notes-40))|
+`doOnRequest`|| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))|
`doOnSubscribe`||||||
-`doOnSuccess`| ([49](#notes-49))| ([49](#notes-49))||| ([37](#notes-37))|
+`doOnSuccess`| ([52](#notes-52))| ([52](#notes-52))||| ([40](#notes-40))|
`doOnTerminate`||||||
-`elementAt`||| ([50](#notes-50))| ([51](#notes-51))| ([37](#notes-37))|
-`elementAtOrError`||| ([52](#notes-52))| ([51](#notes-51))| ([37](#notes-37))|
-`empty`|||| ([23](#notes-23))| ([53](#notes-53))|
+`elementAt`||| ([53](#notes-53))| ([54](#notes-54))| ([40](#notes-40))|
+`elementAtOrError`||| ([55](#notes-55))| ([54](#notes-54))| ([40](#notes-40))|
+`empty`|||| ([23](#notes-23))| ([56](#notes-56))|
`error`||||||
-`filter`||||| ([37](#notes-37))|
-`first`||| ([54](#notes-54))| ([55](#notes-55))| ([38](#notes-38))|
-`firstElement`||| ([56](#notes-56))| ([57](#notes-57))| ([2](#notes-2))|
-`firstOrError`||| ([56](#notes-56))| ([57](#notes-57))| ([58](#notes-58))|
-`firstOrErrorStage`||| ([59](#notes-59))| ([59](#notes-59))| ([60](#notes-60))|
-`firstStage`||| ([59](#notes-59))| ([59](#notes-59))| ([59](#notes-59))|
+`filter`||||| ([40](#notes-40))|
+`first`||| ([57](#notes-57))| ([58](#notes-58))| ([41](#notes-41))|
+`firstElement`||| ([59](#notes-59))| ([60](#notes-60))| ([2](#notes-2))|
+`firstOrError`||| ([59](#notes-59))| ([60](#notes-60))| ([61](#notes-61))|
+`firstOrErrorStage`||| ([62](#notes-62))| ([62](#notes-62))| ([63](#notes-63))|
+`firstStage`||| ([62](#notes-62))| ([62](#notes-62))| ([62](#notes-62))|
`flatMap`||||| ([27](#notes-27))|
`flatMapCompletable`||||| ([27](#notes-27))|
-`flatMapIterable`||| ([30](#notes-30))| ([30](#notes-30))| ([27](#notes-27))|
-`flatMapMaybe`||| ([61](#notes-61))|| ([27](#notes-27))|
-`flatMapObservable`| ([62](#notes-62))| ([63](#notes-63))||| ([27](#notes-27))|
-`flatMapPublisher`| ([63](#notes-63))| ([64](#notes-64))||| ([27](#notes-27))|
-`flatMapSingle`|||| ([61](#notes-61))| ([27](#notes-27))|
-`flatMapSingleElement`| ([65](#notes-65))| ([65](#notes-65))|| ([63](#notes-63))| ([27](#notes-27))|
-`flatMapStream`||| ([33](#notes-33))| ([33](#notes-33))| ([27](#notes-27))|
-`flattenAsFlowable`| ([66](#notes-66))| ([66](#notes-66))||| ([27](#notes-27))|
-`flattenAsObservable`| ([66](#notes-66))| ([66](#notes-66))||| ([27](#notes-27))|
-`flattenStreamAsFlowable`| ([67](#notes-67))| ([67](#notes-67))||| ([27](#notes-27))|
-`flattenStreamAsObservable`| ([67](#notes-67))| ([67](#notes-67))||| ([27](#notes-27))|
-`forEach`||| ([68](#notes-68))| ([68](#notes-68))| ([68](#notes-68))|
-`forEachWhile`||| ([68](#notes-68))| ([68](#notes-68))| ([68](#notes-68))|
+`flatMapIterable`||| ([31](#notes-31))| ([31](#notes-31))| ([27](#notes-27))|
+`flatMapMaybe`||| ([64](#notes-64))|| ([27](#notes-27))|
+`flatMapObservable`| ([65](#notes-65))| ([66](#notes-66))||| ([27](#notes-27))|
+`flatMapPublisher`| ([66](#notes-66))| ([67](#notes-67))||| ([27](#notes-27))|
+`flatMapSingle`|||| ([64](#notes-64))| ([27](#notes-27))|
+`flatMapSingleElement`| ([68](#notes-68))| ([68](#notes-68))|| ([66](#notes-66))| ([27](#notes-27))|
+`flatMapStream`||| ([36](#notes-36))| ([36](#notes-36))| ([27](#notes-27))|
+`flattenAsFlowable`| ([69](#notes-69))| ([69](#notes-69))||| ([27](#notes-27))|
+`flattenAsObservable`| ([69](#notes-69))| ([69](#notes-69))||| ([27](#notes-27))|
+`flattenStreamAsFlowable`| ([70](#notes-70))| ([70](#notes-70))||| ([27](#notes-27))|
+`flattenStreamAsObservable`| ([70](#notes-70))| ([70](#notes-70))||| ([27](#notes-27))|
+`forEach`||| ([71](#notes-71))| ([71](#notes-71))| ([71](#notes-71))|
+`forEachWhile`||| ([71](#notes-71))| ([71](#notes-71))| ([71](#notes-71))|
`fromAction`|||| ([23](#notes-23))||
-`fromArray`||| ([69](#notes-69))| ([70](#notes-70))| ([71](#notes-71))|
+`fromArray`||| ([72](#notes-72))| ([73](#notes-73))| ([74](#notes-74))|
`fromCallable`||||||
-`fromCompletable`|||| ([72](#notes-72))| ([73](#notes-73))|
+`fromCompletable`|||| ([75](#notes-75))| ([76](#notes-76))|
`fromCompletionStage`||||||
`fromFuture`||||||
-`fromIterable`||| ([69](#notes-69))| ([70](#notes-70))| ([71](#notes-71))|
-`fromMaybe`||| ([73](#notes-73))|||
-`fromObservable`|| ([73](#notes-73))||||
-`fromOptional`|||| ([70](#notes-70))| ([71](#notes-71))|
+`fromIterable`||| ([72](#notes-72))| ([73](#notes-73))| ([74](#notes-74))|
+`fromMaybe`||| ([76](#notes-76))|||
+`fromObservable`|| ([76](#notes-76))||||
+`fromOptional`|||| ([73](#notes-73))| ([74](#notes-74))|
`fromPublisher`||||||
`fromRunnable`|||| ([23](#notes-23))||
-`fromSingle`|||| ([73](#notes-73))||
-`fromStream`||| ([69](#notes-69))| ([70](#notes-70))| ([71](#notes-71))|
+`fromSingle`|||| ([76](#notes-76))||
+`fromStream`||| ([72](#notes-72))| ([73](#notes-73))| ([74](#notes-74))|
`fromSupplier`||||||
-`generate`||| ([74](#notes-74))| ([74](#notes-74))| ([74](#notes-74))|
-`groupBy`||| ([75](#notes-75))| ([75](#notes-75))| ([76](#notes-76))|
-`groupJoin`||| ([75](#notes-75))| ([75](#notes-75))| ([77](#notes-77))|
+`generate`||| ([77](#notes-77))| ([77](#notes-77))| ([77](#notes-77))|
+`groupBy`||| ([78](#notes-78))| ([78](#notes-78))| ([79](#notes-79))|
+`groupJoin`||| ([78](#notes-78))| ([78](#notes-78))| ([80](#notes-80))|
`hide`||||||
-`ignoreElement`| ([78](#notes-78))| ([78](#notes-78))||| ([2](#notes-2))|
-`ignoreElements`||| ([79](#notes-79))| ([79](#notes-79))| ([2](#notes-2))|
-`interval`||| ([80](#notes-80))| ([80](#notes-80))| ([80](#notes-80))|
-`intervalRange`||| ([80](#notes-80))| ([80](#notes-80))| ([80](#notes-80))|
-`isEmpty`|||| ([55](#notes-55))| ([2](#notes-2))|
-`join`||| ([81](#notes-81))| ([81](#notes-81))| ([77](#notes-77))|
+`ignoreElement`| ([81](#notes-81))| ([81](#notes-81))||| ([2](#notes-2))|
+`ignoreElements`||| ([82](#notes-82))| ([82](#notes-82))| ([2](#notes-2))|
+`interval`||| ([83](#notes-83))| ([83](#notes-83))| ([83](#notes-83))|
+`intervalRange`||| ([83](#notes-83))| ([83](#notes-83))| ([83](#notes-83))|
+`isEmpty`|||| ([58](#notes-58))| ([2](#notes-2))|
+`join`||| ([84](#notes-84))| ([84](#notes-84))| ([80](#notes-80))|
`just`||||| ([2](#notes-2))|
-`last`||| ([54](#notes-54))| ([55](#notes-55))| ([38](#notes-38))|
-`lastElement`||| ([56](#notes-56))| ([57](#notes-57))| ([2](#notes-2))|
-`lastOrError`||| ([56](#notes-56))| ([57](#notes-57))| ([58](#notes-58))|
-`lastOrErrorStage`||| ([59](#notes-59))| ([59](#notes-59))| ([60](#notes-60))|
-`lastStage`||| ([59](#notes-59))| ([59](#notes-59))| ([59](#notes-59))|
+`last`||| ([57](#notes-57))| ([58](#notes-58))| ([41](#notes-41))|
+`lastElement`||| ([59](#notes-59))| ([60](#notes-60))| ([2](#notes-2))|
+`lastOrError`||| ([59](#notes-59))| ([60](#notes-60))| ([61](#notes-61))|
+`lastOrErrorStage`||| ([62](#notes-62))| ([62](#notes-62))| ([63](#notes-63))|
+`lastStage`||| ([62](#notes-62))| ([62](#notes-62))| ([62](#notes-62))|
`lift`||||||
`map`||||| ([27](#notes-27))|
`mapOptional`||||| ([27](#notes-27))|
@@ -144,100 +144,100 @@ Operator | |||||
`never`||||||
`observeOn`||||||
-`ofType`||||| ([82](#notes-82))|
-`onBackpressureBuffer`|| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))|
-`onBackpressureDrop`|| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))|
-`onBackpressureLatest`|| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))|
+`ofType`||||| ([85](#notes-85))|
+`onBackpressureBuffer`|| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))|
+`onBackpressureDrop`|| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))|
+`onBackpressureLatest`|| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))|
`onErrorComplete`||||||
`onErrorResumeNext`||||||
`onErrorResumeWith`||||||
`onErrorReturn`||||||
`onErrorReturnItem`||||||
`onTerminateDetach`||||||
-`parallel`|| ([83](#notes-83))| ([83](#notes-83))| ([83](#notes-83))| ([83](#notes-83))|
-`publish`||| ([84](#notes-84))| ([85](#notes-85))| ([86](#notes-86))|
-`range`||| ([87](#notes-87))| ([87](#notes-87))| ([71](#notes-71))|
-`rangeLong`||| ([87](#notes-87))| ([87](#notes-87))| ([71](#notes-71))|
-`rebatchRequests`|| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))| ([48](#notes-48))|
-`reduce`||| ([88](#notes-88))| ([88](#notes-88))| ([89](#notes-89))|
-`reduceWith`||| ([88](#notes-88))| ([88](#notes-88))| ([89](#notes-89))|
+`parallel`|| ([86](#notes-86))| ([86](#notes-86))| ([86](#notes-86))| ([86](#notes-86))|
+`publish`||| ([87](#notes-87))| ([88](#notes-88))| ([89](#notes-89))|
+`range`||| ([90](#notes-90))| ([90](#notes-90))| ([74](#notes-74))|
+`rangeLong`||| ([90](#notes-90))| ([90](#notes-90))| ([74](#notes-74))|
+`rebatchRequests`|| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))| ([51](#notes-51))|
+`reduce`||| ([91](#notes-91))| ([91](#notes-91))| ([92](#notes-92))|
+`reduceWith`||| ([91](#notes-91))| ([91](#notes-91))| ([92](#notes-92))|
`repeat`||||||
`repeatUntil`||||||
`repeatWhen`||||||
-`replay`||| ([84](#notes-84))| ([85](#notes-85))| ([86](#notes-86))|
+`replay`||| ([87](#notes-87))| ([88](#notes-88))| ([89](#notes-89))|
`retry`||||||
`retryUntil`||||||
`retryWhen`||||||
`safeSubscribe`||||||
-`sample`||| ([56](#notes-56))| ([56](#notes-56))| ([37](#notes-37))|
-`scan`||| ([88](#notes-88))| ([88](#notes-88))| ([89](#notes-89))|
-`scanWith`||| ([88](#notes-88))| ([88](#notes-88))| ([89](#notes-89))|
+`sample`||| ([59](#notes-59))| ([59](#notes-59))| ([40](#notes-40))|
+`scan`||| ([91](#notes-91))| ([91](#notes-91))| ([92](#notes-92))|
+`scanWith`||| ([91](#notes-91))| ([91](#notes-91))| ([92](#notes-92))|
`sequenceEqual`||||||
-`serialize`||| ([90](#notes-90))| ([90](#notes-90))| ([90](#notes-90))|
-`share`||| ([84](#notes-84))| ([85](#notes-85))| ([86](#notes-86))|
-`single`||| ([54](#notes-54))| ([55](#notes-55))| ([38](#notes-38))|
-`singleElement`||| ([56](#notes-56))| ([57](#notes-57))| ([2](#notes-2))|
-`singleOrError`||| ([56](#notes-56))| ([57](#notes-57))| ([58](#notes-58))|
-`singleOrErrorStage`||| ([59](#notes-59))| ([59](#notes-59))| ([60](#notes-60))|
-`singleStage`||| ([59](#notes-59))| ([59](#notes-59))| ([59](#notes-59))|
-`skip`||| ([56](#notes-56))| ([56](#notes-56))| ([56](#notes-56))|
-`skipLast`||| ([56](#notes-56))| ([56](#notes-56))| ([56](#notes-56))|
-`skipUntil`||| ([91](#notes-91))| ([91](#notes-91))| ([91](#notes-91))|
-`skipWhile`||| ([92](#notes-92))| ([92](#notes-92))| ([2](#notes-2))|
-`sorted`||| ([75](#notes-75))| ([75](#notes-75))| ([75](#notes-75))|
+`serialize`||| ([93](#notes-93))| ([93](#notes-93))| ([93](#notes-93))|
+`share`||| ([87](#notes-87))| ([88](#notes-88))| ([89](#notes-89))|
+`single`||| ([57](#notes-57))| ([58](#notes-58))| ([41](#notes-41))|
+`singleElement`||| ([59](#notes-59))| ([60](#notes-60))| ([2](#notes-2))|
+`singleOrError`||| ([59](#notes-59))| ([60](#notes-60))| ([61](#notes-61))|
+`singleOrErrorStage`||| ([62](#notes-62))| ([62](#notes-62))| ([63](#notes-63))|
+`singleStage`||| ([62](#notes-62))| ([62](#notes-62))| ([62](#notes-62))|
+`skip`||| ([59](#notes-59))| ([59](#notes-59))| ([59](#notes-59))|
+`skipLast`||| ([59](#notes-59))| ([59](#notes-59))| ([59](#notes-59))|
+`skipUntil`||| ([94](#notes-94))| ([94](#notes-94))| ([94](#notes-94))|
+`skipWhile`||| ([95](#notes-95))| ([95](#notes-95))| ([2](#notes-2))|
+`sorted`||| ([78](#notes-78))| ([78](#notes-78))| ([78](#notes-78))|
`startWith`||||||
-`startWithArray`||| ([93](#notes-93))| ([93](#notes-93))| ([93](#notes-93))|
-`startWithItem`||| ([94](#notes-94))| ([94](#notes-94))| ([94](#notes-94))|
-`startWithIterable`||| ([95](#notes-95))| ([95](#notes-95))| ([95](#notes-95))|
+`startWithArray`||| ([96](#notes-96))| ([96](#notes-96))| ([96](#notes-96))|
+`startWithItem`||| ([97](#notes-97))| ([97](#notes-97))| ([97](#notes-97))|
+`startWithIterable`||| ([98](#notes-98))| ([98](#notes-98))| ([98](#notes-98))|
`subscribe`||||||
`subscribeOn`||||||
`subscribeWith`||||||
-`switchIfEmpty`|||| ([23](#notes-23))| ([96](#notes-96))|
-`switchMap`||| ([97](#notes-97))| ([97](#notes-97))| ([27](#notes-27))|
-`switchMapCompletable`||| ([97](#notes-97))| ([97](#notes-97))| ([27](#notes-27))|
-`switchMapCompletableDelayError`||| ([97](#notes-97))| ([97](#notes-97))| ([27](#notes-27))|
-`switchMapDelayError`||| ([97](#notes-97))| ([97](#notes-97))| ([27](#notes-27))|
-`switchMapMaybe`||| ([97](#notes-97))| ([97](#notes-97))| ([27](#notes-27))|
-`switchMapMaybeDelayError`||| ([97](#notes-97))| ([97](#notes-97))| ([27](#notes-27))|
-`switchMapSingle`||| ([97](#notes-97))| ([97](#notes-97))| ([27](#notes-27))|
-`switchMapSingleDelayError`||| ([97](#notes-97))| ([97](#notes-97))| ([27](#notes-27))|
+`switchIfEmpty`|||| ([23](#notes-23))| ([99](#notes-99))|
+`switchMap`||| ([100](#notes-100))| ([100](#notes-100))| ([27](#notes-27))|
+`switchMapCompletable`||| ([100](#notes-100))| ([100](#notes-100))| ([27](#notes-27))|
+`switchMapCompletableDelayError`||| ([100](#notes-100))| ([100](#notes-100))| ([27](#notes-27))|
+`switchMapDelayError`||| ([100](#notes-100))| ([100](#notes-100))| ([27](#notes-27))|
+`switchMapMaybe`||| ([100](#notes-100))| ([100](#notes-100))| ([27](#notes-27))|
+`switchMapMaybeDelayError`||| ([100](#notes-100))| ([100](#notes-100))| ([27](#notes-27))|
+`switchMapSingle`||| ([100](#notes-100))| ([100](#notes-100))| ([27](#notes-27))|
+`switchMapSingleDelayError`||| ([100](#notes-100))| ([100](#notes-100))| ([27](#notes-27))|
`switchOnNext`||||||
`switchOnNextDelayError`||||||
-`take`||| ([56](#notes-56))| ([56](#notes-56))| ([56](#notes-56))|
-`takeLast`||| ([56](#notes-56))| ([56](#notes-56))| ([56](#notes-56))|
+`take`||| ([59](#notes-59))| ([59](#notes-59))| ([59](#notes-59))|
+`takeLast`||| ([59](#notes-59))| ([59](#notes-59))| ([59](#notes-59))|
`takeUntil`||||||
-`takeWhile`||| ([92](#notes-92))| ([92](#notes-92))| ([2](#notes-2))|
+`takeWhile`||| ([95](#notes-95))| ([95](#notes-95))| ([2](#notes-2))|
`test`||||||
-`throttleFirst`||| ([36](#notes-36))| ([36](#notes-36))| ([37](#notes-37))|
-`throttleLast`||| ([36](#notes-36))| ([36](#notes-36))| ([37](#notes-37))|
-`throttleLatest`||| ([36](#notes-36))| ([36](#notes-36))| ([37](#notes-37))|
-`throttleWithTimeout`||| ([36](#notes-36))| ([36](#notes-36))| ([37](#notes-37))|
-`timeInterval`||||| ([37](#notes-37))|
+`throttleFirst`||| ([39](#notes-39))| ([39](#notes-39))| ([40](#notes-40))|
+`throttleLast`||| ([39](#notes-39))| ([39](#notes-39))| ([40](#notes-40))|
+`throttleLatest`||| ([39](#notes-39))| ([39](#notes-39))| ([40](#notes-40))|
+`throttleWithTimeout`||| ([39](#notes-39))| ([39](#notes-39))| ([40](#notes-40))|
+`timeInterval`||||| ([40](#notes-40))|
`timeout`||||||
`timer`||||||
-`timestamp`||||| ([37](#notes-37))|
+`timestamp`||||| ([40](#notes-40))|
`to`||||||
-`toCompletionStage`| ([98](#notes-98))| ([98](#notes-98))||||
-`toFlowable`| ([99](#notes-99))|||||
+`toCompletionStage`| ([101](#notes-101))| ([101](#notes-101))||||
+`toFlowable`| ([102](#notes-102))|||||
`toFuture`||||||
`toList`||| ([13](#notes-13))| ([14](#notes-14))| ([15](#notes-15))|
`toMap`||| ([13](#notes-13))| ([14](#notes-14))| ([15](#notes-15))|
-`toMaybe`| ([100](#notes-100))| ([100](#notes-100))| ([99](#notes-99))|||
+`toMaybe`| ([103](#notes-103))| ([103](#notes-103))| ([102](#notes-102))|||
`toMultimap`||| ([13](#notes-13))| ([14](#notes-14))| ([15](#notes-15))|
-`toObservable`|| ([99](#notes-99))||||
-`toSingle`| ([101](#notes-101))| ([101](#notes-101))|| ([99](#notes-99))||
-`toSingleDefault`| ([102](#notes-102))| ([102](#notes-102))| ([103](#notes-103))| ([99](#notes-99))||
+`toObservable`|| ([102](#notes-102))||||
+`toSingle`| ([104](#notes-104))| ([104](#notes-104))|| ([102](#notes-102))||
+`toSingleDefault`| ([105](#notes-105))| ([105](#notes-105))| ([106](#notes-106))| ([102](#notes-102))||
`toSortedList`||| ([13](#notes-13))| ([14](#notes-14))| ([15](#notes-15))|
`unsafeCreate`||||||
`unsubscribeOn`||||||
`using`||||||
-`window`||| ([104](#notes-104))| ([105](#notes-105))| ([106](#notes-106))|
+`window`||| ([107](#notes-107))| ([108](#notes-108))| ([109](#notes-109))|
`withLatestFrom`||| ([16](#notes-16))| ([16](#notes-16))| ([17](#notes-17))|
-`wrap`| ([107](#notes-107))|||||
-`zip`||||| ([108](#notes-108))|
-`zipArray`||||| ([109](#notes-109))|
-`zipWith`||||| ([110](#notes-110))|
-**237 operators** | **215** | **209** | **113** | **97** | **78** |
+`wrap`| ([110](#notes-110))|||||
+`zip`||||| ([111](#notes-111))|
+`zipArray`||||| ([112](#notes-112))|
+`zipWith`||||| ([113](#notes-113))|
+**237 operators** | **215** | **209** | **115** | **100** | **78** |
#### Notes
1 Use [`contains()`](#contains).
@@ -269,87 +269,90 @@ Operator |  or the mapped-in source, but never both. Use [`concatMapCompletable`](#concatMapCompletable). 29 Either the upstream fails (thus no inner) or the mapped-in source, but never both. Use [`concatMap`](#concatMap).
-30 At most one item. Use [`flattenAsFlowable`](#flattenAsFlowable) or [`flattenAsObservable`](#flattenAsObservable).
-31 Either the upstream fails (thus no inner) or the mapped-in source, but never both. Use [`concatMapMaybe`](#concatMapMaybe).
-32 Either the upstream fails (thus no inner) or the mapped-in source, but never both. Use [`concatMapSingle`](#concatMapSingle).
-33 At most one item. Use [`flattenStreamAsFlowable`](#flattenStreamAsFlowable) or [`flattenStreamAsObservable`](#flattenStreamAsObservable).
-34 Never empty thus always 1.
-35 Always empty thus always 0.
-36 At most one item signaled so no subsequent items to work with.
-37 Always empty thus no items to work with.
-38 Always empty. Use [`andThen()`](#andThen) to chose the follow-up sequence.
-39 At most one item, always distinct.
-40 Different terminology. Use [`doAfterSuccess()`](#doAfterSuccess).
-41 Different terminology. Use [`doAfterNext()`](#doAfterNext).
-42 Different terminology. Use [`doOnDispose()`](#doOnDispose).
-43 Always succeeds or fails, there is no `onComplete` signal.
-44 Different terminology. Use [`doOnCancel()`](#doOnCancel).
-45 At most one item. Use [`doOnEvent()`](#doOnEvent).
-46 Use [`doOnEach()`](#doOnEach).
-47 Different terminology. Use [`doOnSuccess()`](#doOnSuccess).
-48 Backpressure related and not supported outside `Flowable`.
-49 Different terminology. Use [`doOnNext()`](#doOnNext).
-50 At most one item with index 0. Use [`defaultIfEmpty`](#defaultIfEmpty).
-51 Always one item with index 0.
-52 At most one item with index 0. Use [`toSingle`](#toSingle).
-53 Use [`complete()`](#complete).
-54 At most one item. Use [`defaultIfEmpty`](#defaultIfEmpty).
-55 Always one item.
-56 At most one item, would be no-op.
-57 Always one item, would be no-op.
-58 Always empty. Use [`andThen()`](#andThen) and [`error()`](#error).
-59 At most one item. Use [`toCompletionStage()`](#toCompletionStage).
-60 Always empty. Use [`andThen()`](#andThen), [`error()`](#error) and [`toCompletionStage()`](#toCompletionStage).
-61 Use [`flatMap()`](#flatMap).
-62 Not supported. Use [`flatMap`](#flatMap) and [`toFlowable()`](#toFlowable).
-63 Use [`flatMap`](#flatMap).
-64 Not supported. Use [`flatMap`](#flatMap) and [`toObservable()`](#toFlowable).
-65 Use [`flatMapSingle`](#flatMapSingle).
-66 Use [`flatMapIterable()`](#flatMapIterable).
-67 Use [`flatMapStream()`](#flatMapStream).
-68 Use [`subscribe()`](#subscribe).
-69 At most one item. Use [`just()`](#just) or [`empty()`](#empty).
-70 Always one item. Use [`just()`](#just).
-71 Always empty. Use [`complete()`](#complete).
-72 Always error.
-73 Use [`wrap()`](#wrap).
-74 Use [`fromSupplier()`](#fromSupplier).
-75 At most one item.
-76 Always empty thus no items to group.
-77 Always empty thus no items to join.
-78 Use [`ignoreElements()`](#ignoreElements).
-79 Use [`ignoreElement()`](#ignoreElement).
-80 At most one item. Use [`timer()`](#timer).
-81 At most one item. Use [`zip()`](#zip)
-82 Always empty thus no items to filter.
-83 Needs backpressure thus not supported outside `Flowable`.
-84 Connectable sources not supported outside `Flowable` and `Observable`. Use a `MaybeSubject`.
-85 Connectable sources not supported outside `Flowable` and `Observable`. Use a `SingleSubject`.
-86 Connectable sources not supported outside `Flowable` and `Observable`. Use a `ConnectableSubject`.
-87 At most one item. Use [`just()`](#just).
-88 At most one item. Use [`map()`](#map).
-89 Always empty thus no items to reduce.
-90 At most one signal type.
-91 At most one item. Use [`takeUntil()`](#takeUntil).
-92 At most one item. Use [`filter()`](#filter).
-93 Use [`startWith()`](#startWith) and [`fromArray()`](#fromArray) of `Flowable` or `Observable`.
-94 Use [`startWith()`](#startWith) and [`just()`](#just) of another reactive type.
-95 Use [`startWith()`](#startWith) and [`fromIterable()`](#fromArray) of `Flowable` or `Observable`.
-96 Always empty. Use [`defaultIfEmpty()`](#defaultIfEmpty).
-97 At most one item. Use [`flatMap()`](#flatMap).
-98 Use [`firstStage`](#firstStage), [`lastStage`](#lastStage) or [`singleStage`](#singleStage).
-99 Would be no-op.
-100 Use [`firstElement`](#firstElement), [`lastElement`](#lastElement) or [`singleElement`](#singleElement).
-101 Use [`firstOrError`](#firstOrError), [`lastOrError`](#lastOrError) or [`singleOrError`](#singleOrError).
-102 Use [`first`](#first), [`last`](#last) or [`single`](#single).
-103 Use [`defaultIfEmpty()`](#defaultIfEmpty).
-104 Use [`map()`](#map) and [`switchIfEmpty()`](#switchIfEmpty) to transform into a nested source.
-105 Use [`map()`](#map) to transform into a nested source.
-106 Always empty. Use [`andThen()`](#andThen) to bring in a nested source.
-107 Use [`fromPublisher()`](#fromPublisher).
-108 Use [`merge()`](#merge).
-109 Use [`mergeArray()`](#mergeArray).
-110 Use [`mergeWith()`](#mergeWith).
+30 At most one item to map. Use [`concatMap()`](#concatMap).
+31 At most one item. Use [`flattenAsFlowable`](#flattenAsFlowable) or [`flattenAsObservable`](#flattenAsObservable).
+32 Use [`concatMap`](#concatMap).
+33 Either the upstream fails (thus no inner) or the mapped-in source, but never both. Use [`concatMapMaybe`](#concatMapMaybe).
+34 Use [`concatMap()`](#concatMap).
+35 Either the upstream fails (thus no inner) or the mapped-in source, but never both. Use [`concatMapSingle`](#concatMapSingle).
+36 At most one item. Use [`flattenStreamAsFlowable`](#flattenStreamAsFlowable) or [`flattenStreamAsObservable`](#flattenStreamAsObservable).
+37 Never empty thus always 1.
+38 Always empty thus always 0.
+39 At most one item signaled so no subsequent items to work with.
+40 Always empty thus no items to work with.
+41 Always empty. Use [`andThen()`](#andThen) to chose the follow-up sequence.
+42 At most one item, always distinct.
+43 Different terminology. Use [`doAfterSuccess()`](#doAfterSuccess).
+44 Different terminology. Use [`doAfterNext()`](#doAfterNext).
+45 Different terminology. Use [`doOnDispose()`](#doOnDispose).
+46 Always succeeds or fails, there is no `onComplete` signal.
+47 Different terminology. Use [`doOnCancel()`](#doOnCancel).
+48 At most one item. Use [`doOnEvent()`](#doOnEvent).
+49 Use [`doOnEach()`](#doOnEach).
+50 Different terminology. Use [`doOnSuccess()`](#doOnSuccess).
+51 Backpressure related and not supported outside `Flowable`.
+52 Different terminology. Use [`doOnNext()`](#doOnNext).
+53 At most one item with index 0. Use [`defaultIfEmpty`](#defaultIfEmpty).
+54 Always one item with index 0.
+55 At most one item with index 0. Use [`toSingle`](#toSingle).
+56 Use [`complete()`](#complete).
+57 At most one item. Use [`defaultIfEmpty`](#defaultIfEmpty).
+58 Always one item.
+59 At most one item, would be no-op.
+60 Always one item, would be no-op.
+61 Always empty. Use [`andThen()`](#andThen) and [`error()`](#error).
+62 At most one item. Use [`toCompletionStage()`](#toCompletionStage).
+63 Always empty. Use [`andThen()`](#andThen), [`error()`](#error) and [`toCompletionStage()`](#toCompletionStage).
+64 Use [`flatMap()`](#flatMap).
+65 Not supported. Use [`flatMap`](#flatMap) and [`toFlowable()`](#toFlowable).
+66 Use [`flatMap`](#flatMap).
+67 Not supported. Use [`flatMap`](#flatMap) and [`toObservable()`](#toFlowable).
+68 Use [`flatMapSingle`](#flatMapSingle).
+69 Use [`flatMapIterable()`](#flatMapIterable).
+70 Use [`flatMapStream()`](#flatMapStream).
+71 Use [`subscribe()`](#subscribe).
+72 At most one item. Use [`just()`](#just) or [`empty()`](#empty).
+73 Always one item. Use [`just()`](#just).
+74 Always empty. Use [`complete()`](#complete).
+75 Always error.
+76 Use [`wrap()`](#wrap).
+77 Use [`fromSupplier()`](#fromSupplier).
+78 At most one item.
+79 Always empty thus no items to group.
+80 Always empty thus no items to join.
+81 Use [`ignoreElements()`](#ignoreElements).
+82 Use [`ignoreElement()`](#ignoreElement).
+83 At most one item. Use [`timer()`](#timer).
+84 At most one item. Use [`zip()`](#zip)
+85 Always empty thus no items to filter.
+86 Needs backpressure thus not supported outside `Flowable`.
+87 Connectable sources not supported outside `Flowable` and `Observable`. Use a `MaybeSubject`.
+88 Connectable sources not supported outside `Flowable` and `Observable`. Use a `SingleSubject`.
+89 Connectable sources not supported outside `Flowable` and `Observable`. Use a `ConnectableSubject`.
+90 At most one item. Use [`just()`](#just).
+91 At most one item. Use [`map()`](#map).
+92 Always empty thus no items to reduce.
+93 At most one signal type.
+94 At most one item. Use [`takeUntil()`](#takeUntil).
+95 At most one item. Use [`filter()`](#filter).
+96 Use [`startWith()`](#startWith) and [`fromArray()`](#fromArray) of `Flowable` or `Observable`.
+97 Use [`startWith()`](#startWith) and [`just()`](#just) of another reactive type.
+98 Use [`startWith()`](#startWith) and [`fromIterable()`](#fromArray) of `Flowable` or `Observable`.
+99 Always empty. Use [`defaultIfEmpty()`](#defaultIfEmpty).
+100 At most one item. Use [`flatMap()`](#flatMap).
+101 Use [`firstStage`](#firstStage), [`lastStage`](#lastStage) or [`singleStage`](#singleStage).
+102 Would be no-op.
+103 Use [`firstElement`](#firstElement), [`lastElement`](#lastElement) or [`singleElement`](#singleElement).
+104 Use [`firstOrError`](#firstOrError), [`lastOrError`](#lastOrError) or [`singleOrError`](#singleOrError).
+105 Use [`first`](#first), [`last`](#last) or [`single`](#single).
+106 Use [`defaultIfEmpty()`](#defaultIfEmpty).
+107 Use [`map()`](#map) and [`switchIfEmpty()`](#switchIfEmpty) to transform into a nested source.
+108 Use [`map()`](#map) to transform into a nested source.
+109 Always empty. Use [`andThen()`](#andThen) to bring in a nested source.
+110 Use [`fromPublisher()`](#fromPublisher).
+111 Use [`merge()`](#merge).
+112 Use [`mergeArray()`](#mergeArray).
+113 Use [`mergeWith()`](#mergeWith).
#### Under development
@@ -359,26 +362,13 @@ Operator | 
5. Single.concatDelayError()
6. Completable.concatDelayError()
-7. Single.concatMap()
-8. Maybe.concatMapCompletable()
-9. Single.concatMapCompletable()
-10. Maybe.concatMapEager()
-11. Single.concatMapEager()
-12. Completable.concatMapEager()
-13. Maybe.concatMapEagerDelayError()
-14. Single.concatMapEagerDelayError()
-15. Completable.concatMapEagerDelayError()
-16. Maybe.concatMapMaybe()
-17. Single.concatMapMaybe()
-18. Maybe.concatMapSingle()
-19. Single.concatMapSingle()
-20. Single.mergeArray()
-21. Single.mergeArrayDelayError()
-22. Completable.onErrorReturn()
-23. Completable.onErrorReturnItem()
-24. Maybe.safeSubscribe()
-25. Single.safeSubscribe()
-26. Completable.safeSubscribe()
-27. Completable.sequenceEqual()
-28. Maybe.startWith()
-29. Single.startWith()
+7. Single.mergeArray()
+8. Single.mergeArrayDelayError()
+9. Completable.onErrorReturn()
+10. Completable.onErrorReturnItem()
+11. Maybe.safeSubscribe()
+12. Single.safeSubscribe()
+13. Completable.safeSubscribe()
+14. Completable.sequenceEqual()
+15. Maybe.startWith()
+16. Single.startWith()
diff --git a/src/main/java/io/reactivex/rxjava3/core/Maybe.java b/src/main/java/io/reactivex/rxjava3/core/Maybe.java
index b3ed8213d4..6754f65e7b 100644
--- a/src/main/java/io/reactivex/rxjava3/core/Maybe.java
+++ b/src/main/java/io/reactivex/rxjava3/core/Maybe.java
@@ -2828,12 +2828,13 @@ public final Maybe compose(@NonNull MaybeTransformer super T, ? extends
* Returns a {@code Maybe} that is based on applying a specified function to the item emitted by the current {@code Maybe},
* where that function returns a {@link MaybeSource}.
*
- *
+ *
+ *
+ * Note that flatMap and concatMap for {@code Maybe} is the same operation.
*
*
Scheduler:
*
{@code concatMap} does not operate by default on a particular {@link Scheduler}.
*
- *
Note that flatMap and concatMap for {@code Maybe} is the same operation.
* @param the result value type
* @param mapper
* a function that, when applied to the item emitted by the current {@code Maybe}, returns a {@code MaybeSource}
@@ -2845,8 +2846,63 @@ public final Maybe compose(@NonNull MaybeTransformer super T, ? extends
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Maybe concatMap(@NonNull Function super T, ? extends MaybeSource extends R>> mapper) {
- Objects.requireNonNull(mapper, "mapper is null");
- return RxJavaPlugins.onAssembly(new MaybeFlatten<>(this, mapper));
+ return flatMap(mapper);
+ }
+
+ /**
+ * Returns a {@link Completable} that completes based on applying a specified function to the item emitted by the
+ * current {@code Maybe}, where that function returns a {@code Completable}.
+ *
+ *
+ *
+ * This operator is an alias for {@link #flatMapCompletable(Function)}.
+ *
+ *
Scheduler:
+ *
{@code concatMapCompletable} does not operate by default on a particular {@link Scheduler}.
+ *
+ *
+ * @param mapper
+ * a function that, when applied to the item emitted by the current {@code Maybe}, returns a
+ * {@code Completable}
+ * @return the new {@code Completable} instance
+ * @throws NullPointerException if {@code mapper} is {@code null}
+ * @see ReactiveX operators documentation: FlatMap
+ * @since 3.0.0
+ */
+ @CheckReturnValue
+ @NonNull
+ @SchedulerSupport(SchedulerSupport.NONE)
+ public final Completable concatMapCompletable(@NonNull Function super T, ? extends CompletableSource> mapper) {
+ return flatMapCompletable(mapper);
+ }
+
+ /**
+ * Returns a {@code Maybe} based on applying a specified function to the item emitted by the
+ * current {@code Maybe}, where that function returns a {@link Single}.
+ * When this {@code Maybe} just completes the resulting {@code Maybe} completes as well.
+ *
+ *
+ *
+ * This operator is an alias for {@link #flatMapSingleElement(Function)}.
+ *
+ *
Scheduler:
+ *
{@code concatMapSingle} does not operate by default on a particular {@link Scheduler}.
+ *
+ *
+ * @param the result value type
+ * @param mapper
+ * a function that, when applied to the item emitted by the current {@code Maybe}, returns a
+ * {@code Single}
+ * @return the new {@code Maybe} instance
+ * @throws NullPointerException if {@code mapper} is {@code null}
+ * @see ReactiveX operators documentation: FlatMap
+ * @since 3.0.0
+ */
+ @CheckReturnValue
+ @NonNull
+ @SchedulerSupport(SchedulerSupport.NONE)
+ public final Maybe concatMapSingle(@NonNull Function super T, ? extends SingleSource extends R>> mapper) {
+ return flatMapSingleElement(mapper);
}
/**
@@ -3732,7 +3788,7 @@ public final Flowable flatMapPublisher(@NonNull Function super T, ? ext
* current {@code Maybe}, where that function returns a {@code Single}.
* When this {@code Maybe} completes a {@link NoSuchElementException} will be thrown.
*
- *
+ *
*
*
Scheduler:
*
{@code flatMapSingle} does not operate by default on a particular {@link Scheduler}.
@@ -3759,7 +3815,7 @@ public final Single flatMapSingle(@NonNull Function super T, ? extends
* current {@code Maybe}, where that function returns a {@link Single}.
* When this {@code Maybe} just completes the resulting {@code Maybe} completes as well.
*
- *
+ *
*
*
Scheduler:
*
{@code flatMapSingleElement} does not operate by default on a particular {@link Scheduler}.
@@ -3787,7 +3843,7 @@ public final Maybe flatMapSingleElement(@NonNull Function super T, ? ex
* Returns a {@link Completable} that completes based on applying a specified function to the item emitted by the
* current {@code Maybe}, where that function returns a {@code Completable}.
*
- *
+ *
*
*
Scheduler:
*
{@code flatMapCompletable} does not operate by default on a particular {@link Scheduler}.
diff --git a/src/main/java/io/reactivex/rxjava3/core/Single.java b/src/main/java/io/reactivex/rxjava3/core/Single.java
index 81b0aaaffe..0a1d872b14 100644
--- a/src/main/java/io/reactivex/rxjava3/core/Single.java
+++ b/src/main/java/io/reactivex/rxjava3/core/Single.java
@@ -2278,6 +2278,86 @@ public final Single cast(@NonNull Class extends U> clazz) {
return map(Functions.castFunction(clazz));
}
+ /**
+ * Returns a {@code Single} that is based on applying a specified function to the item emitted by the current {@code Single},
+ * where that function returns a {@link SingleSource}.
+ *
+ *
+ *
+ * The operator is an alias for {@link #flatMap(Function)}
+ *
+ *
Scheduler:
+ *
{@code concatMap} does not operate by default on a particular {@link Scheduler}.
+ *
+ *
+ * @param the result value type
+ * @param mapper
+ * a function that, when applied to the item emitted by the current {@code Single}, returns a {@code SingleSource}
+ * @return the new {@code Single} returned from {@code mapper} when applied to the item emitted by the current {@code Single}
+ * @throws NullPointerException if {@code mapper} is {@code null}
+ * @see ReactiveX operators documentation: FlatMap
+ */
+ @CheckReturnValue
+ @NonNull
+ @SchedulerSupport(SchedulerSupport.NONE)
+ public final Single concatMap(@NonNull Function super T, ? extends SingleSource extends R>> mapper) {
+ Objects.requireNonNull(mapper, "mapper is null");
+ return RxJavaPlugins.onAssembly(new SingleFlatMap<>(this, mapper));
+ }
+
+ /**
+ * Returns a {@link Completable} that completes based on applying a specified function to the item emitted by the
+ * current {@code Single}, where that function returns a {@link CompletableSource}.
+ *
+ *
+ *
+ * The operator is an alias for {@link #flatMapCompletable(Function)}.
+ *
+ *
Scheduler:
+ *
{@code concatMapCompletable} does not operate by default on a particular {@link Scheduler}.
+ *
+ *
+ * @param mapper
+ * a function that, when applied to the item emitted by the current {@code Single}, returns a
+ * {@code CompletableSource}
+ * @return the new {@code Completable} instance
+ * @throws NullPointerException if {@code mapper} is {@code null}
+ * @see ReactiveX operators documentation: FlatMap
+ * @since 3.0.0
+ */
+ @CheckReturnValue
+ @NonNull
+ @SchedulerSupport(SchedulerSupport.NONE)
+ public final Completable concatMapCompletable(@NonNull Function super T, ? extends CompletableSource> mapper) {
+ return flatMapCompletable(mapper);
+ }
+
+ /**
+ * Returns a {@link Maybe} that is based on applying a specified function to the item emitted by the current {@code Single},
+ * where that function returns a {@link MaybeSource}.
+ *
+ *
+ *
+ * The operator is an alias for {@link #flatMapMaybe(Function)}.
+ *
+ *
Scheduler:
+ *
{@code concatMapMaybe} does not operate by default on a particular {@link Scheduler}.
+ *
+ *
+ * @param the result value type
+ * @param mapper
+ * a function that, when applied to the item emitted by the current {@code Single}, returns a {@code MaybeSource}
+ * @return the new {@code Maybe} returned from {@code mapper} when applied to the item emitted by the current {@code Single}
+ * @throws NullPointerException if {@code mapper} is {@code null}
+ * @see ReactiveX operators documentation: FlatMap
+ */
+ @CheckReturnValue
+ @NonNull
+ @SchedulerSupport(SchedulerSupport.NONE)
+ public final Maybe concatMapMaybe(@NonNull Function super T, ? extends MaybeSource extends R>> mapper) {
+ return flatMapMaybe(mapper);
+ }
+
/**
* Returns a {@link Flowable} that emits the item emitted by the current {@code Single}, then the item emitted by the
* specified {@link SingleSource}.
diff --git a/src/test/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatMapCompletableTest.java b/src/test/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatMapCompletableTest.java
new file mode 100644
index 0000000000..e902bbf4df
--- /dev/null
+++ b/src/test/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatMapCompletableTest.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2016-present, RxJava Contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
+ * the License for the specific language governing permissions and limitations under the License.
+ */
+
+package io.reactivex.rxjava3.internal.operators.maybe;
+
+import org.junit.Test;
+
+import io.reactivex.rxjava3.core.*;
+import io.reactivex.rxjava3.exceptions.TestException;
+import io.reactivex.rxjava3.functions.Function;
+import io.reactivex.rxjava3.testsupport.TestHelper;
+
+public class MaybeConcatMapCompletableTest extends RxJavaTest {
+
+ @Test
+ public void dispose() {
+ TestHelper.checkDisposed(Maybe.just(1).concatMapCompletable(new Function() {
+ @Override
+ public Completable apply(Integer v) throws Exception {
+ return Completable.complete();
+ }
+ }));
+ }
+
+ @Test
+ public void mapperThrows() {
+ Maybe.just(1)
+ .concatMapCompletable(new Function() {
+ @Override
+ public Completable apply(Integer v) throws Exception {
+ throw new TestException();
+ }
+ })
+ .test()
+ .assertFailure(TestException.class);
+ }
+
+ @Test
+ public void mapperReturnsNull() {
+ Maybe.just(1)
+ .concatMapCompletable(new Function() {
+ @Override
+ public Completable apply(Integer v) throws Exception {
+ return null;
+ }
+ })
+ .test()
+ .assertFailure(NullPointerException.class);
+ }
+}
diff --git a/src/test/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatMapSingleTest.java b/src/test/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatMapSingleTest.java
new file mode 100644
index 0000000000..2626b18e26
--- /dev/null
+++ b/src/test/java/io/reactivex/rxjava3/internal/operators/maybe/MaybeConcatMapSingleTest.java
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2016-present, RxJava Contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
+ * the License for the specific language governing permissions and limitations under the License.
+ */
+
+package io.reactivex.rxjava3.internal.operators.maybe;
+
+import org.junit.Test;
+
+import io.reactivex.rxjava3.core.*;
+import io.reactivex.rxjava3.exceptions.TestException;
+import io.reactivex.rxjava3.functions.Function;
+import io.reactivex.rxjava3.testsupport.TestHelper;
+
+public class MaybeConcatMapSingleTest extends RxJavaTest {
+ @Test
+ public void flatMapSingleElementValue() {
+ Maybe.just(1).concatMapSingle(new Function>() {
+ @Override public SingleSource apply(final Integer integer) throws Exception {
+ if (integer == 1) {
+ return Single.just(2);
+ }
+
+ return Single.just(1);
+ }
+ })
+ .test()
+ .assertResult(2);
+ }
+
+ @Test
+ public void flatMapSingleElementValueDifferentType() {
+ Maybe.just(1).concatMapSingle(new Function>() {
+ @Override public SingleSource apply(final Integer integer) throws Exception {
+ if (integer == 1) {
+ return Single.just("2");
+ }
+
+ return Single.just("1");
+ }
+ })
+ .test()
+ .assertResult("2");
+ }
+
+ @Test
+ public void flatMapSingleElementValueNull() {
+ Maybe.just(1).concatMapSingle(new Function>() {
+ @Override public SingleSource apply(final Integer integer) throws Exception {
+ return null;
+ }
+ })
+ .to(TestHelper.testConsumer())
+ .assertNoValues()
+ .assertError(NullPointerException.class)
+ .assertErrorMessage("The mapper returned a null SingleSource");
+ }
+
+ @Test
+ public void flatMapSingleElementValueErrorThrown() {
+ Maybe.just(1).concatMapSingle(new Function>() {
+ @Override public SingleSource apply(final Integer integer) throws Exception {
+ throw new RuntimeException("something went terribly wrong!");
+ }
+ })
+ .to(TestHelper.testConsumer())
+ .assertNoValues()
+ .assertError(RuntimeException.class)
+ .assertErrorMessage("something went terribly wrong!");
+ }
+
+ @Test
+ public void flatMapSingleElementError() {
+ RuntimeException exception = new RuntimeException("test");
+
+ Maybe.error(exception).concatMapSingle(new Function