RxJava

RxJava Operators

Operators are the building blocks of reactive programming with RxJava. They allow you to transform, filter, combine, and manipulate data streams in powerful ways.

Operator Categories

RxJava provides a rich set of operators organized into different categories based on their purpose:

Creation Operators

Create Observable sequences from various sources.

just fromArray fromIterable interval range

Transforming Operators

Transform items emitted by Observables.

map flatMap switchMap buffer scan

Filtering Operators

Filter items emitted by Observables.

filter take skip distinct debounce

Combining Operators

Combine multiple Observables.

merge concat zip combineLatest withLatestFrom

Error Handling Operators

Handle errors in Observable sequences.

onErrorReturn onErrorResumeNext retry retryWhen

Utility Operators

Perform actions on Observable sequences.

delay doOnNext doOnError timeout timestamp

Essential Operators

map

Transforms each item emitted by an Observable by applying a function to each item.

Example

1Observable.just("Hello, World!")
2 .map(s -> s.toUpperCase())
3 .subscribe(result -> System.out.println(result));
4
5// Output: HELLO, WORLD!
Marble Diagram
--1--2--3--4-->
   map(x => x*x)
--1--4--9-16-->
When to Use

When you need to transform each item in a 1:1 relationship without changing the number of items.

Similar To

select in LINQ, Array.map() in JavaScript

filter

Emits only those items from an Observable that pass a predicate test.

Example

1Observable.fromArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
2 .filter(n -> n % 2 == 0) // Keep only even numbers
3 .subscribe(n -> System.out.println(n));
4
5// Output: 2, 4, 6, 8, 10
Marble Diagram
--1--2--3--4--5-->
 filter(x => x % 2 == 0)
----2-----4------>
When to Use

When you need to exclude items that don't meet certain criteria.

Similar To

where in LINQ, Array.filter() in JavaScript

flatMap

Transforms items emitted by an Observable into Observables, then flattens the emissions.

Example

1// Simulate fetching user details after fetching user IDs
2Observable.just("user1", "user2", "user3")
3 .flatMap(userId -> getUserDetails(userId))
4 .subscribe(userDetails -> System.out.println(userDetails));
5
6// Where getUserDetails is defined as:
7private Observable<String> getUserDetails(String userId) {
8 return Observable.just("Details for " + userId);
9}
Marble Diagram
--1--------2------>
  flatMap(x => [x, x+1])
--1-2------2-3---->
When to Use

When you need to perform nested asynchronous operations, like API calls that depend on the result of another API call.

Similar To

selectMany in LINQ, Array.flatMap() in JavaScript

debounce

Only emits an item if a specified time period has passed without the Observable emitting another item.

Example

1// In an Android UI context with RxBinding
2RxTextView.textChanges(searchEditText)
3 .debounce(300, TimeUnit.MILLISECONDS) // Wait for 300ms of inactivity
4 .observeOn(AndroidSchedulers.mainThread())
5 .subscribe(query -> performSearch(query.toString()));
Marble Diagram
--1-2-3---4-|-->
   debounce(100ms)
---------3---4-|-->
When to Use

When handling rapid user input like search queries, to avoid making API calls for each keystroke.

Similar To

Debounce functions in UI libraries, lodash's _.debounce()

Operator Selection Guide

Choosing the right operator can be challenging. Here's a quick guide to help you pick the right operator based on your needs:

Need to Transform Items?

  • map: One-to-one transformation of each item
  • flatMap: One-to-many transformation, preserves order but may interleave
  • switchMap: One-to-many transformation, cancels previous inner Observables
  • concatMap: One-to-many transformation, processes inner Observables in order

Need to Filter Items?

  • filter: Remove items that don't satisfy a condition
  • take: Limit the number of items
  • skip: Skip a number of items
  • distinct: Remove duplicate items
  • elementAt: Only emit the item at a specific index

Need to Combine Multiple Observables?

  • merge: Combine multiple Observables, emitting items as they arrive
  • concat: Combine Observables sequentially, one after the other
  • zip: Combine items from multiple Observables into pairs/tuples
  • combineLatest: When any Observable emits, combine with latest from others

Need to Handle Errors?

  • onErrorReturn: Return a default value if error occurs
  • onErrorResumeNext: Switch to a fallback Observable if error occurs
  • retry: Resubscribe to the source Observable if error occurs
  • retryWhen: Resubscribe based on another Observable's emissions