Skip to content

RxJava

Networking & ConcurrencyReactive ProgrammingJava

What it is

RxJava is a Java library for composing asynchronous and event-based programs using observable sequences. It provides powerful operators for managing concurrency, data streams, and transformations in a functional style.

RxJava provides Observable, Flowable, Single, Maybe, and Completable types to handle streams of data. It supports operators like map, filter, merge, flatMap, and error handling operators for reactive programming patterns.

Installation

Add dependency in pom.xml: <dependency> <groupId>io.reactivex.rxjava3</groupId> <artifactId>rxjava</artifactId> <version>3.1.7</version> </dependency>

Getting started

The smallest useful thing you can do with it, and what each part means.

Creating an Observable
import io.reactivex.rxjava3.core.Observable;

Observable<String> observable = Observable.just("Hello", "RxJava", "World");
observable.subscribe(System.out::println);
Creates a simple Observable that emits three strings and prints them.
Using map operator
Observable<Integer> numbers = Observable.just(1, 2, 3, 4);
numbers.map(x -> x * x).subscribe(System.out::println);
Transforms each emitted number by squaring it using the map operator.

Advanced usage

Where the library earns its place over a simpler alternative.

Combining Observables
Observable<String> obs1 = Observable.just("A", "B");
Observable<String> obs2 = Observable.just("1", "2");
Observable.combineLatest(obs1, obs2, (s1, s2) -> s1 + s2).subscribe(System.out::println);
Combines the latest emissions from two Observables.
Error handling
Observable<Integer> numbers = Observable.just(1, 0, 2);
numbers.map(x -> 10 / x).onErrorReturnItem(-1).subscribe(System.out::println);
Handles division by zero errors and provides a default value using onErrorReturnItem.
Using Flowable for backpressure
import io.reactivex.rxjava3.core.Flowable;

Flowable.range(1, 1000)
    .map(x -> x * 2)
    .subscribe(System.out::println);
Handles large streams of data efficiently with Flowable to manage backpressure.
Threading with Schedulers
Observable.just("Hello", "RxJava")
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.single())
    .subscribe(System.out::println);
Specifies different threads for subscription and observation using Schedulers.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

OnErrorNotImplementedException
Occurs if an Observable emits an error but no error handler is provided. Always provide onError callbacks when subscribing.
MissingBackpressureException
Occurs when Flowable emits items faster than downstream can consume. Use strategies like buffer, drop, or latest to manage backpressure.
NullPointerException
RxJava does not allow null emissions. Ensure that no null values are emitted in the stream.

Best practices

  • Use appropriate reactive types (Observable, Flowable, Single, Maybe, Completable) for the scenario.
  • Always manage subscriptions to avoid memory leaks, using Disposable or CompositeDisposable.
  • Use Flowable for streams with large or fast-emitting data to handle backpressure.
  • Prefer functional operators over manual threading and callbacks for cleaner code.
  • Handle errors explicitly using onErrorReturn, onErrorResumeNext, or try-catch in operators.

Background

Why it exists, and what it was reacting to.

RxJava was inspired by the Reactive Extensions (Rx) from Microsoft and was created to bring reactive programming paradigms to Java. It allows developers to handle asynchronous events, multithreading, and reactive streams in a declarative way, improving code readability and reducing boilerplate in complex event-driven applications.