RxJava 2.0 is open source extension to java for asynchronous programming by NetFlix. It is much closer to functional programming as seen in java 8 lambda expressions. The basic building blocks of reactive code are Observables and Subscribers. An Observable
emits items; a Subscriber
consumes those items.
RxJava looks like Observer design pattern too – but with a difference – Observables often don’t start emitting items until someone explicitly subscribes to them.
Table of Contents 1. What is RxJava and Reactive Programming 2. RxJava 2 Dependency 3. Transformation 4. Conclusion
1. What is RxJava and Reactive Programming
Reactive programming is a general programming term that is focused on reacting to changes, such as data values or events. A callback is an approach to reactive programming done imperatively.
For example, if you have one source of data (producer) and one target for data (consumer); then after connecting the consumer to subscriber – reactive programming framework is responsible for pushing the data, generated by the producer, to the consumer. Please note that an observable can have any number of subscribers.
Let’s look at a very basic RxJava hello world example.
package com.howtodoinjava.app; import io.reactivex.Observable; import io.reactivex.functions.Consumer; public class RxJava2Example { public static void main(String[] args) { //producer Observable<String> observable = Observable.just("how", "to", "do", "in", "java"); //consumer Consumer<? super String> consumer = System.out::println; //Attaching producer to consumer observable.subscribe(consumer); } }
In above example, "how", "to", "do", "in", "java"
can be considered as stream of events. An observable
is created for these events. Then we create a consumer
which can act on these words – in this case it is just printing them out to console. This consumer is nothing but the subscriber
.
Lastly, we connect the subscriber to consumer using subscribe()
. As soon as, we connect both, words/events start flowing and subscriber start printing them in console.
Internally in code, when a new word is emitted from the observable, the onNext()
method is called on each subscriber. When the observable finishes all of words either successful or with an error, the onComplete()
or the onError()
method is called on the subscriber.
2. RxJava 2 Dependency
To include RxJava 2.0 into your project runtime, you may choose between given maven config, gradle config or jar file into classpath.
2.1. RxJava 2.0 Maven Dependency
<!-- https://mvnrepository.com/artifact/io.reactivex.rxjava3/rxjava --> <dependency> <groupId>io.reactivex.rxjava2</groupId> <artifactId>rxjava</artifactId> <version>2.1.0</version> </dependency>
2.2. RxJava 2.0 Gradle Dependency
compile group: 'io.reactivex.rxjava2', name: 'rxjava', version: '2.1.0'
2.3. RxJava 2.0 Jar Dependency
Download RxJava 2.0 Jar file link.
3. Transformation in RxJava
In RxJava, the event type which subscriber receive from observable and event type which subscriber emits, do not need to be same. They can be different in data it contain, the data types or any other major difference between received and emitted event.
This is necessary to provide support for intermediate transformation of events between the source and target, so that both work the way they designed for and still they are compatible. It’s much like adapter design pattern.
Let’s take an example. In our hello world example, we want to print the words in UPPERCASE. It is a simple transformation, but you will get the concept.
Observable<String> observable = Observable.just("how", "to", "do", "in", "java"); Consumer<? super String> consumer = System.out::println; //Transformation using map() method observable.map(w -> w.toUpperCase()).subscribe(consumer);
In above example, we have added one intermediate method map()
before subscribing the observable. So every word first goes through map()
method and then goes to subscriber for further handling. It is called transformation.
As mentioned before, you can change the data type of the event as well in transformation process. e.g.
Observable<String> observable = Observable.just("how", "to", "do", "in", "java"); Consumer<? super Integer> consumer = System.out::println; observable.map(w -> w.toUpperCase().hashCode()).subscribe(consumer);
In this program, we are iterating over words and then in transformation we get the hashcode of the word and pass it to subscriber, which print the hashcode in console. So, here we connect the observable, which emits string, and subscriber, which accept integer.
4. Conclusion
The way observable and subscriber are connected loosely, it brings great advantage to developers. They don’t need to think about whole concurrency paradigm, which is already a daunting task for many of us. You just connect the producer and subscriber – and everything just works – flawlessly.
Also, you don’t need to think about both observable and subscriber at same time. You can develop them independently with their best design choices, and then connect them using transformation concept. Great !!
This RxJava Tutorial was more of introduction to RxJava. I will cover it’s important concepts related to reactive programming tutorial in more depth in coming rxjava tutorials for beginners.
Happy Learning !!