RxJava

Language: Java

Reactive Programming

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.

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.

Installation

maven: Add dependency in pom.xml: <dependency> <groupId>io.reactivex.rxjava3</groupId> <artifactId>rxjava</artifactId> <version>3.1.7</version> </dependency>
gradle: Add dependency in build.gradle: implementation 'io.reactivex.rxjava3:rxjava:3.1.7'

Usage

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.

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.

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.

Error Handling

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.