Exploring RxJava in Android — Operators for Transforming Observables
This article is part of RxJava Introduction series. You can checkout the entire series here:
- RxJava Introduction and Operators for creating Observables
- RxJava Operators: Operators for Transforming Observables — You are here
- RxJava Operators: Operators for Filtering Observables
- RxJava Operators: Operators for Combining Observables
- RxJava Operators: Utility Operators
- RxJava Operators: Conditional and Boolean Operators
- RxJava Operators: Mathematical and Aggregate Operators
- RxJava: Different types of Observables
- RxJava: Different types of Subjects
Operators for Transforming Observables
Buffer
This operator periodically gather items from an Observable into bundles and emit these bundles rather than emitting the items one at a time.
Sample Implementation: The below sample transforms an Observable using Observable.buffer()
method. The below code will emit 2 items at a time since the buffer is specified as 2.
Output:
onNext():
String: A
String: B
onNext():
String: C
String: D
onNext():
String: E
String: F
Map
This operator transforms the items emitted by an Observable by applying a function to each item. map()
operator allows for us to modify the emitted item from the Observable and then emits the modified item.
Sample Implementation: In the below code, we have a list of integer values. Using map()
operator, each integer in the list is multiplied by 2 and the result is emitted. Notice that the order of insertion is maintained during emission.
Output:
onNext: 2
onNext: 4
onNext: 6
onNext: 8
onNext: 10
onNext: 12
FlatMap
This operator transforms each item emitted by an Observable but instead of returning the modified item, it returns the Observable itself which can emit data again. In other words, they merge items emitted by multiple Observables and returns a single Observable. The important difference between FlatMap and other transformation operators is that the order in which the items are emitted is not maintained.
Sample Implementation: We are going to follow the same test with the same conditions except instead of map()
we are going to use flatMap()
. Notice that the order of insertion is not maintained.
Output:
onNext: 2
onNext: 6
onNext: 10
onNext: 12
onNext: 4
onNext: 8
SwitchMap
Whenever a new item is emitted by the Observable, it will unsubscribe to the Observable that was generated from the previously emitted item and begin only mirroring the current one. In other words, it returns the latest Observable and emits the items from it.
Sample Implementation: Again we are going to follow the same test with the same conditions, except this time instead of flatMap()
we are going to use switchMap()
. The output of the below code will be 12 because: we are passing a list of integers (1,2,3,4,5,6) and using switchMap()
, multiplying the each integer by 2. switchMap()
always returns the latest Observable and emits from it.
Output:
onNext: 12
ConcatMap
This operator functions the same way as flatMap()
, the difference being in concatMap()
the order in which items are emitted are maintained. One disadvantage of concatMap()
is that it waits for each observable to finish all the work until next one is processed.
Sample Implementation: Again we are going to follow the same test with the same conditions, except this time instead of switchMap()
we are going to use concatMap()
.
Output:
onNext: 2
onNext: 4
onNext: 6
onNext: 8
onNext: 10
onNext: 12
Scenarios we can use the different operators:
- Map operator can be used when we fetch items from the server and need to modify it before emitting to the UI.
- FlatMap operator can be used when we know that the order of the items are not important.
- SwitchMap is best suited for scenarios such as a feed page, when pull to refresh is enabled. When user refreshes the screen, the older feed response is ignored and only the latest request results are emitted to the UI when using a SwitchMap.
GroupBy
This operator divides an Observable into a set of Observables that each emit a different group of items from the original Observable, organised by key.
Sample Implementation: The below code will create an Observable with range of 1 to 10 numbers. We use the groupBy()
operator to emit only even numbers from the list.
Output
onNext: 2
onNext: 4
onNext: 6
onNext: 8
onNext: 10
Scan
This operator Transform each item into another item, like you did with map. But also include the “previous” item when you get around to doing a transform.
Sample Implementation: Let’s explain this operator with an example. Let’s say we have a range of 1 to 10 numbers. The scan()
operator emits two integers at a time. The below code adds the two integers that is emitted and emits the sum.
Output
onNext: 1
onNext: 3
onNext: 6
onNext: 10
onNext: 15
onNext: 21
onNext: 28
onNext: 36
onNext: 45
onNext: 55
That’s it guys! This is part two of the series on RxJava. I hope you enjoyed this article and found it useful, if so please hit the Clap button. Let me know your thoughts in the comments section.
Happy coding!