SlideShare a Scribd company logo
RxJava 2 : Reactive Extensions for
the JVM
NETESH KUMAR
Senior Software Engineer @ Informatica
12/06/2018
Why RxJava ? Why should I Learn new
Programming paradigms ?
● Users expect real time data.
● Users want their tweets now.
● Users want to see their order confirmed now.
● Users need prices accurate as of now.
● Online games need to be responsive.
● As a developer, you demand fire-and-forget messaging.
● You don't want to be blocked waiting for a result.
● You want to have the result pushed to you when it is ready.
● Even better, when working with result sets, you want to receive individual results as they
are ready.
● You do not want to wait for the entire set to be processed before you see the first row.
The world has moved to push;
There are hell lot of reason.
Reactive Programming
A library for Composing Asynchronous and Event Based program using Observable Sequences for the
Java Virtual Machine.
Wikipedia:-
reactive programming is a declarative programming paradigm concerned with data streams and the
propagation of change.
Example:
A B C
fun
add(A,B){ return A+B;}
9 4 13
What is Rx in RxJava
Java VM implementation of
An Api for asynchronous programming with Observable streams. ReactiveX is a combination of the best
ideas from the Observer pattern, the Iterator pattern, and functional programming
A Observable pattern is extended version or combination of Observer and Iterable Design pattern.
Observer & Iterable Design Pattern
Observer Design Pattern:
Define a one-to-many dependency between objects so that when one object changes state, all
its dependents are notified and updated automatically.
Iterator Design Pattern:
Provides a way to access the elements of an aggregate object without exposing its underlying
representation.
Missing in Observer:
● The ability for the producer to signal to the consumer that there is no more data
available.
● The ability for the producer to signal to the consumer that an error has occurred.
Reactive Principles
The Reactive Manifesto:
Let’s look one by one each in next slide
The Reactive Manifesto
Responsive:
a reactive system needs to handle requests in a reasonable time (I let you define
reasonable).
Resilient:
a reactive system must stay responsive in the face of failures (crash, timeout, 500 error
), so it must be designed for failures and deal with them appropriately.
Elastic:
a reactive system must stay responsive under various loads. Consequently, it must scale
up and down, and be able to handle the load with minimal resources.
Message driven:
components from a reactive system interacts using asynchronous message passing.
Build blocks for RxJava
A set of methods for modifying and composing the data.
OBSERVABLES representing sources of data.
SUBSCRIBERS or OBSERVERS listening to the OBSERVABLES.
SCHEDULERS
Source Consumer
OBSERVABLE SUBSCRIBER
onNext( )
onCompleted( )
onError( )
onNext() working style
Application of RxJava
Client Side
Example: Thread switching, event handling and more.
Server Side
Example: Request
Response
Microservice A
Microservice B
Microservice C
Business Logic
Types Of Observables In RxJava
Observable — Operator — Observer
Observable Operator
Observer
Different Types of Observables and Observers
OBSERVABLES OBSERVERS
● Observable
● Flowable
● Single
● Maybe
● Completable
● Observer
● SingleObserver
● MaybeObserver
● CompletableObserver
Let’s look all Observable and Observer in details:-
Observable <> Observer
It is the simplest Observable which can emit more than one value.
use-case: Let’s say you are downloading something and you have to push the status of
download percentage.
Example:
Observable<String> observable = Observable.just(“A”,”B”,”C”).subscribe(System.out::println);
Output:
A
B
C
Flowable <> Observer
Use-case: Flowable comes to picture when there is a case that the Observable is emitting huge numbers
of values which can’t be consumed by the Observer.
In this case, the Observable needs to skip some values on the basis of some strategy else it will throw an
exception.
The Flowable Observable handles the exception with a strategy.
The strategy is called BackPressureStrategy and the exception is called MissingBackPressureException.
Go to BackPressure Slide
Single <> Single Observer
Use-case: Single is used when the Observable has to emit only one value like a response from a
network call.
Example:
Single.just("Hello").subscribe(System.out::println,Throwable::printStackTrace);
Observable observable = Observable.just("A","B","C");
observable.first("Nil").subscribe(System.out::println);
Output:
Hello
A
Maybe <> Maybe Observer
Use-case: Maybe is used when the Observable has to emit a value or no value.
Example:
Maybe<String> maybe = Maybe.just("Hi");
maybe.subscribe(System.out::println);
Maybe<String> maybe_two = Maybe.empty();
maybe_two.subscribe(System.out::println);
Output:
Hi
Completable <> Completable Observer
Use-case: Completable is used when the Observable has to do some task without emitting a
value.
Example:
private static void running() {
System.out.println("I am doing some task!");
}
Completable.fromRunnable(()->running()).subscribe(()->System.out.println("Done!"));
Output:
I am doing some task!
Done!
Cold vs Hot vs Multicasting Observable
There are subtle behaviors in a relationship between an Observable and an Observer depending
on how the Observable is implemented.
Cold Observables
Cold Observables will replay the emissions to each Observer, ensuring that all Observers get all
the data.
Real Time Examples:
Cold Observables are much like a pendrive or CD player, that can be replayed to each listener,
so each person can hear all the tracks at any time.
Will have Demo in coming slide
Hot Observable
If an Observer subscribes to a hot Observable, receives some emissions, and then another
Observer comes in afterwards, that second Observer will have missed those emissions.
Real Time Example:
A hot Observable is more like a radio or tv station. It broadcasts the same emissions to all
Observers at the same time.
Connectable or Multicasting Observable
A helpful form of hot Observable is ConnectableObservable. It will take any Observable, even if it is cold,
and make it hot so that all emissions are played to all Observers at once.
To make it:-
just add publish() to any observable.
And add observable.connect() to start firing the emissions.
ConnectableObservable<String> observable=Observable.just(Alpha","Beta","Gamma").publish();
observable.subscribe(System.out::println);
observable.subscribe(System.out::println);
observable.connect();
Let’s se few image to understand it better, like what all we can do.
It’s self-explanatory, so explaining in ppt. If you want to look code, find in my github
Creating Observable :- with just()
Observable.just("Hello") - Allows to create an observable as wrapper around other data types
Observable<String> observable = Observable.just(“a”, “b”, “c”, “d”, “e”);
Subscriber<String> my_subscriber = Subscribers.create(
n->System.out.println(n);
e->System.out.println(“Error ”+e);
()->System.out.println(“Completed);
);
observable.subscribe(my_subscriber);
Can be written like:
Observable<String> observable = Observable.just(“a”, “b”, “c”, “d”, “e”).subscribe(System.out::prinltn);
Output:
a
b
c
d
e
Completed
Creating Observable :- with create()
Observable<String> observable = Observable.create(emitter -> {
try {
List<String> todos = getTodos();
for (String todo : todos) {
emitter.onNext(todo);
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});
observable.subscribe(s->System.out.println(s), Throwable::printStackTrace);
Can be written :
Disposable disposable = observable .subscribe(t -> System.out.print(t),e -> e.printStackTrace());
disposable.dispose();
getTodos=[“a”,”b”,”c”]
Output:
a
b
c
Creating Observable :- with fromArray()
Observable.fromArray() - takes an array and emits their values in their order in the data
structure
List<Integer> list = Arrays.asList(1,2,3,4,5);
Observable<List<Integer>> observable = Observable.fromArray(list);
observable.subscribe(System.out::println);
Output:
[1,2,3,4,5]
Creating Observable :- with fromIterable()
Observable.fromIterable() - takes an java.lang.Iterable<T> and emits their values in their order
in the data structure
List<Integer> list = Arrays.asList(1,2,3,4,5);
Observable<Integer> observable = Observable.fromIterable(list);
observable.subscribe(System.out::println);
Output:
1
2
3
4
5
Creating Observable :- with fromCallable()
Observable.fromCallable() is great for converting a single function into an Observable.
Method -> getStudentName()
Observable.fromCallable(new Callable<Object>() {
@Override
public Object call() throws Exception {
return getStudentInfo();
}
}).subscribe(System.out::println);
Can be written like:
Observable.fromCallable(()->getStudentName()).subscribe(System.out::println);
Creating Observable :- with fromFuture()
Observable.fromFuture() - Allows to create an observable for a java.util.concurrent.Future
if we have existing libraries that yield Futures, you can easily turn them into Observables via
Observable.future().
Example:-
Future<String> futureValue = ...;
Observable.fromFuture(futureValue).subscribe(System.out::println);
Creating Observable :- with range()
Observable.range():-Returns an Observable that emits a sequence of Integers within a specified
range
Int start = 1; int count = 5;
Observable observable = Observable.range(start,count).subscribe(System.out::println);
Output:
1
2
3
4
5
Creating Observable :- with interval()
Observable.interval() - An observable that emits Long objects in a given interval
Observable observable = Observable.interval(3, TimeUnit.SECONDS);
observable.subscribe(System.out::println);
sleep(5000);
Output:
0
1
2
3,
4
Creating Observable :- with empty()
Observable.empty(): For creating empty stream.
Observable.never(): This is same as empty(), except one minor difference. It will never
terminate or get called onComplete() method.
Observable.error(): will only get used for testing.
Observable<String> empty = Observable.empty();
empty.subscribe( System.out::println,
Throwable::printStackTrace,
() -> System.out.println("Done!")
);
Output:
Done!
Creating Observable :- with defer()
Observable.defer(): is ability to create a separate state for each Observer.if your source is
stateful and you want to create a separate state for each Observer.
Int start=1;int count=3;
Observable<Integer> source = Observable.defer(() -> Observable.range(start,count));
source.subscribe(System.out::println);
count=5;
source.subscribe(System.out::println);
Output:
1
2
3
1
2
3
4
5
Operators
Operators applies in between source and destination.
Observable
Subscriber
Operator 1
Operator 2
Operator n
Operators By Category
Type of Operators:
Creating Observables Conditional and Boolean Operators
Transforming Observables Mathematical and Aggregate Operators
Filtering Observables Backpressure Operators
Combining Observables Connectable Observable Operators
Error Handling Operators Operators to Convert Observables
Observable Utility Operators
Let’s look some of them...
Skip()
Skip: Suppress the first n items emitted by an Observable.
Example:
Observable<Integer> observable = Observable.range(1,100);
observable.skip(95).subscribe(System.out::println);
Output:
96
97
98
99
100
Filtering Observables
There are many filtering option available in rxjava, let’s see few example out of them.
● Debounce — only emit an item from an Observable if a particular timespan has passed without it emitting another item.
● Distinct — suppress duplicate items emitted by an Observable.
● ElementAt — emit only item n emitted by an Observable.
● Filter — emit only those items from an Observable that pass a predicate test.
● First — emit only the first item, or the first item that meets a condition, from an Observable.
● IgnoreElements — do not emit any items from an Observable but mirror its termination notification.
● Last — emit only the last item emitted by an Observable.
● Sample — emit the most recent item emitted by an Observable within periodic time intervals.
● Skip — suppress the first n items emitted by an Observable.
● SkipLast — suppress the last n items emitted by an Observable.
● Take — emit only the first n items emitted by an Observable.
● TakeLast — emit only the last n items emitted by an Observable.
filter()
Filter: Emit only those items from an Observable that pass a predicate test
Example:
Observable<Integer> observable = Observable.just(1,4,3,2,6,7,9,13,14,32); observable.filter(i-
>i%2==0).subscribe(System.out::println);
Output:
4
2
6
14
32
DistinctUntilChanged()
DistinctUntilChanged: The distinctUntilChanged() function will ignore duplicate consecutive
emissions.
Look rxmarbles:
http://www.rxmarbles.com/#distinctUntilChanged
Example:
Observable<Integer> observable = Observable.just(1,1,2,2,3,1,1,2);
observable.distinctUntilChanged().subscribe(System.out::println);
Output:
1
2
3
1
2
Transforming Observables
Operators that transform items that are emitted by an Observable.
Buffer — periodically gather items from an Observable into bundles and emit these bundles rather
than emitting the items one at a time
FlatMap — transform the items emitted by an Observable into Observables, then flatten the
emissions from those into a single Observable
GroupBy — divide an Observable into a set of Observables that each emit a different group of
items from the original Observable, organized by key
Map — transform the items emitted by an Observable by applying a function to each item
Scan — apply a function to each item emitted by an Observable, sequentially, and emit each
successive value
Window — periodically subdivide items from an Observable into Observable windows and emit
these windows rather than emitting the items one at a time
Let’s Understand flatMap()
It performs a dynamic
Observable.merge() by taking each
emission and maps into in
Observable.
Note: It doesn’t maintain order, for
maintaining order you can user
concatMap().
Let’s Understand by looking in
example.
flatMap() Example
Let’s Say I have Number/Special character and String, Now we want to make observable of only
Number. So here is perfect example.
Observable<String> observable =
Observable.just(
"521934/2342/FOXTROT", "21962/12112/78886/TANGO",
"283242/4542/WHISKEY/2348562");
observable
.flatMap(s -> Observable.fromArray(s.split("/")))
.filter(s -> s.matches("[0-9]+"))
.map(Integer::valueOf)
.subscribe(System.out::println);
Output:
521934
2342
21962
12112
78886
283242
4542
2348562
Let’s Understand groupBy()
It’s similar operator like SQL,
even much more. Can be grouped
by key, value etc…
Let’s Understand by looking in
example:
groupBy() Example
Observable<String> observable = Observable.just("Alpha", "Beta", "Gamma", "Delta",
"Epsilon");
Observable<GroupedObservable<Integer,String>> groupedObservableObservable =
observable.groupBy(String::length);
groupedObservableObservable.flatMapSingle(s -> s.toList()).subscribe(System.out::println);
Output:
[Beta]
[Alpha, Gamma, Delta]
[Epsilon]
Combining Observables
Operators that work with multiple source Observables to create a single Observable
And/Then/When — combine sets of items emitted by two or more Observables by means of
Pattern and Plan intermediaries
CombineLatest — when an item is emitted by either of two Observables, combine the latest
item emitted by each Observable via a specified function and emit items based on the results of
this function
Join — combine items emitted by two Observables whenever an item from one Observable is
emitted during a time window defined according to an item emitted by the other Observable
Merge — combine multiple Observables into one by merging their emissions
StartsWith — emit a specified sequence of items before beginning to emit the items from the
source Observable
Switch — convert an Observable that emits Observables into a single Observable that emits the
items emitted by the most-recently-emitted of those Observables
Zip — combine the emissions of multiple Observables together via a specified function and emit
single items for each combination based on the results of this function
Let’s Understand merger() using Diagram
The Observable.merge() operator
will take two or more
Observable<T> sources emitting
the same type T and then
consolidate them into a single
Observable<T>
Note:
merge() and mergerWith(): doesn't
give order guarantee.
concat(): It’s give guarantee.
Understanding merge() by Example
Observable<String> observable = Observable.just("A","B","C");
Observable<String> observable2 = Observable.just("A1","B1","C1");
Observable.merge(observable,observable2).subscribe(System.out::println);
Output:
A
B
C
A1
B1
C1
As you can see output comes in order but it’s not guarantee.
Note: you can create a list of observable array and pass it to Observable.mergeArray(list).
Understanding concat() using Diagram
Concat: emit the emissions from two or more Observables without interleaving them
Understanding zip()
Zip: It takes an emission from each
Observable source and combine it
into a single emission
Note: Observable can emit different
type.
Understanding zip() using Example
Observable<String> observable = Observable.just("Bahubali","Singham");
Observable<Integer> observable1 = Observable.range(1,10);
Observable.zip(observable,observable1,(s,i)-> s+" - "+i).subscribe(System.out::println);
Output:
Bahubali - 1
Singham - 2
There are bunch of operator available in rxjava.
Error Handling Operators
Operators that help to recover from error notifications from an Observable
Catch — recover from an onError notification by continuing the sequence without error
Retry — if a source Observable sends an onError notification, resubscribe to it in the hopes that
it will complete without error
onErrorReturnand or onErrorReturnItem -For resort to a default value when an exception
occurs
onErrorResumeNext- similar to onErrorReturned but accepts another Observable as a
parameter to emit potentially multiple values
Handling Errors in Rxjava
Let’s take common example: dividing number by 0. If you do not catch exception then your
program terminate.Am I right huh?
Same case with RxJava but little change, let’s understand via example:
Observable<Integer> observable = Observable.just(4,2,0,3,7,6);
observable.map(i->10/i).subscribe(s->System.out.println(s),e->System.out.println(e));
Output:
2
5
java.lang.ArithmeticException: / by zero
Looks cool: But how to return default value instead of error or how to retry again and again.
Let’s discuss in another slide.
onErrorReturn() and onErrorReturnItem()
Let’s understand by example:
Observable<Integer> observable = Observable.just(4,2,0,3,7,6);
observable.map(i->10/i).onErrorReturnItem(-1).subscribe(System.out::println);
observable.map(i->10/i).onErrorReturn(e->-1).subscribe(s->System.out.println(s),e-
>System.out.println(e));
Output:
2
5
-1
onErrorResumeNext()
Let’s understand by example:
Observable<Integer> observable = Observable.just(4,2,0,3,7,6);
observable.map(i->10/i).onErrorResumeNext(Observable.just(-1).repeat(3)).subscribe(
s->System.out.println(s),
e->System.out.println(e)
);
Output:
2
5
-1
-1
-1
retry()
Another way of recovery is retry().
Let’s understand by example:
Observable<Integer> observable = Observable.just(4,2,0,3,7,6);
observable.map(i->10/i).retry(2).subscribe(s->System.out.println(s),e->System.out.println(e));
It will retry two time because we have mention in argument.
Output:
2
5
2
5
java.lang.ArithmeticException: / by zero
Conditional and Boolean Operators
Operators that evaluate one or more Observables or items emitted by Observables
All — determine whether all items emitted by an Observable meet some criteria
Amb — given two or more source Observables, emit all of the items from only the first of these
Observables to emit an item
Contains — determine whether an Observable emits a particular item or not
DefaultIfEmpty — emit items from the source Observable, or a default item if the source
Observable emits nothing
SequenceEqual — determine whether two Observables emit the same sequence of items
SkipUntil — discard items emitted by an Observable until a second Observable emits an item
SkipWhile — discard items emitted by an Observable until a specified condition becomes false
TakeUntil — discard items emitted by an Observable after a second Observable emits an item or
terminates
TakeWhile — discard items emitted by an Observable after a specified condition becomes false
Ambiguous
Ambiguous: when you have multiple sources for the same data or events and you want the
fastest one to win.
Let’s say we have two server (ServerA and ServerB) any of then can give me response. Now
customer made a request for data, whoever gives me data first, we will accept data from that
server.(I am talking in terms of Observable)
Api will look like:
Observable.amb(“can pass list or two observable).subscribe(System.out::println);
Mathematical and Aggregate Operators
It’s simple to use mathematical operator, not covering in ppt. If you want to find the code for all,
please visit my github page.s
Operators that operate on the entire sequence of items emitted by an Observable
Average — calculates the average of numbers emitted by an Observable and emits this average
Concat — emit the emissions from two or more Observables without interleaving them
Count — count the number of items emitted by the source Observable and emit only this value
Max — determine, and emit, the maximum-valued item emitted by an Observable
Min — determine, and emit, the minimum-valued item emitted by an Observable
Reduce — apply a function to each item emitted by an Observable, sequentially, and emit the
final value
Sum — calculate the sum of numbers emitted by an Observable and emit this sum
Action Operators
Apply these operator for getting visibility into an Observable chain
● doOnNext(), doOnComplete() and doOnError()
● doOnSubscibe(), doOnDispose() and doOnSuccess()
All are pretty simple, I won’t discuss all, let me take one example and show you.
Observable<Integer> observable = Observable.just(4,2,0,3,7,6);
observable.doOnNext(s->System.out.println("Processing:"+s))
.map(i->10/i).subscribe(s->System.out.println(s),e->System.out.println(e));
Output:
Processing:4
2
Processing:2
5
Processing:0
java.lang.ArithmeticException: / by zero
Types of Subject in RxJava
Subject: A Subject is a sort of bridge or proxy that is available in some implementations of
ReactiveX that acts both as an observer and as an Observable. Because it is an observer, it can
subscribe to one or more Observables, and because it is an Observable, it can pass through the
items it observes by re-emitting them, and it can also emit new items.
● PublishSubject
● ReplaySubject
● BehaviorSubject
● AsyncSubject
PublishSubject
PublishSubject emits to an observer only those
items that are emitted by the source Observable(s)
subsequent to the time of the subscription.
Use-case:
if a student entered late into the classroom, he just
wants to listen from that point of time when he
entered the classroom, PublishSubject will be best
choice.
ReplaySubject
ReplaySubject: It emits all the items of
the source Observable, regardless of
when the subscriber subscribes.
Use-case:
if a student entered late into the
classroom, he wants to listen from the
beginning.
BehaviorSubject
BehaviorSubject:
It emits the most recently emitted item
and all the subsequent items of the
source Observable when an observer
subscribes to it.
Use-case:
if a student entered late into the
classroom, he wants to listen the
most recent things(not from the
beginning) being taught by the
professor so that he gets the idea of
the context.
AsyncSubject
AsyncSubject:
It only emits the last value of the
source Observable(and only the
last value)
Use-case:
if a student entered at any point of
time into the classroom, and he
wants to listen only about the last
thing(and only the last thing) being
taught
Disposable in RxJava
It is use for unsubscribe from source (observable).
This also used for avoid memory leak.
Let’s take some real problem and try to solve:
Use-case:
An Application do many operation in background, and many time can happen that background
task is no longer need, in that situation we must have a way to unsubscribe from source.
Example: when you start some task, and you forgot to stop, in that case you can get memory
leak. So to avoid memory leak we can use disposable.
clear() will clear all, but can accept new disposable.
dispose() will clear all and set isDisposed = true, so it will not accept any new disposable.
Handling subscriber with Disposable
Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS);
Disposable disposable = observable.subscribe(System.out::println);
Thread.sleep(5000);
disposable.dispose();
Thread.sleep(5000);
Output:
0
1
2
3
After dispose() it will not print any result.
What if multiple subscriber listening to observable ?
Handling multiple subscriber with Disposable
To handle multiple subscriber we have compositedisposable() in rxjava. Let’s see how?
Step 1: create composite disposable
Step 2: Add all disposable to composite disposable
Step 3: call dispose() method.
Example:
private static final CompositeDisposable disposables = new CompositeDisposable();
Observable<Long> seconds = Observable.interval(1, TimeUnit.SECONDS);
Disposable disposable1 = seconds.subscribe(l -> System.out.println("Observer 1: " + l));
Disposable disposable2 = seconds.subscribe(l -> System.out.println("Observer 2: " + l));
disposables.addAll(disposable1, disposable2);
sleep(5000);
disposables.dispose();
sleep(5000);
Handle rapidly fired emission in RxJava
Let’s checkout some operators that help rapidly firing sources without using back pressure and
are especially appropriate for situations where backpressure cannot be utilized.
● Buffering
● Windowing
● Throttling
● Switching
Understanding buffer() in RxJava
It emit each batch as a list or
another collection type.
buffer() operator will gather
emissions within a certain scope,
like list,map etc…
example:
fixed-size buffering
time-based buffering
boundary-based buffering
Let’s understand by looking in
example.
Understanding fixed size buffer using
Example
This is the best example for sending data in chunk.
Observable.range(1,36).buffer(10).subscribe(System.out::println);
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
[31, 32, 33, 34, 35, 36]
Understanding time based buffer using
Example
Observable.interval(1, TimeUnit.SECONDS)
.map(s->s+100)
.buffer(3,TimeUnit.SECONDS)
.subscribe(System.out::println);
sleep(9000);
Output:
[100, 101]
[102, 103, 104, 105]
[106, 107]
Understanding boundary-based buffer
using Example
It accept another Observable as a boundary argument.
It does not matter what type this other Observable emits.
Observable<Long> boundary = Observable.interval(1,TimeUnit.SECONDS);
Observable.interval(300,TimeUnit.MILLISECONDS).buffer(boundary).subscribe(System.out::pr
intln);
Output:
[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[9, 10, 11, 12]
[13, 14, 15]
[16, 17, 18, 19]
Understanding window() in RxJava
window() is similar to buffer, except
it emits in other observable rather
than collections.
Let’s understand by looking
example
Understanding window() using Example
Fixed-size Example:
Observable.range(1,50).window(5)
.flatMapSingle(s->s.toList())
.subscribe(System.out::println);
Output:
[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]
[11, 12, 13, 14, 15]
[16, 17, 18]
Time-Based Example:
Observable.interval(1,
TimeUnit.MILLISECONDS)
.map(i->i+100)
.window(1,TimeUnit.SECONDS)
.flatMapSingle(s->s.toList())
.subscribe(System.out::println);
Boundary-Based Example:
It’s is similar to boundary-based buffer.
Understanding throttling() in RxJava
buffer() and windows() batch up
source emission into collection or
observable.
But throttle() omits emission when
emission occur rapidly.
Use-case: if user click on button
rapidly
throttleLast()/ sample()
throttleFirst()
throttleWithTimeout/ debounce()
Understanding throttleLast() using Example
Observable.interval(100, TimeUnit.MILLISECONDS).take(7).subscribe(s->System.out.println(" source 1: "+s));
Observable.interval(400, TimeUnit.MILLISECONDS).take(3).subscribe(s->System.out.println(" source 2: "+s));
Observable.interval(900, TimeUnit.MILLISECONDS).take(2).subscribe(s->System.out.println(" source 3: "+s));
Output:
source 1: 0
source 1: 1
source 1: 2
source 1: 3
source 2: 0
source 1: 4
source 1: 5
source 1: 6
source 2: 1
source 3: 0
source 2: 2
source 3: 1
Let’s check, How to apply throttleLast().
Observable.concat(source1,source2,source3).throttleLast(1,TimeUnit.SECONDS).subsc
ribe(s->System.out.println(" source : "+s));
Output:
source : 6
source : 2
source : 0
source : 1
Note: throttleFirst() is similar to throttleLast(), so not covering.
Understanding switching() in Rxjava
SwitchMap: SwitchMap would emit
only the latest observable after a
particular delay. It ignores all the
previous ones.
It is useful when it comes to
retrieving the latest data from a
feed. It’s useful when you need to
identify the latest among many
feeds.
Backpressure in RxJava
Backpressure relates to a mechanism through which the subscriber can signal to the producer
how much data it can consume and so to produce only that amount.
When a source is emitting more items rapidly than an operator or subscriber can consume
them, then the item that are overflowing from publisher need to be handled.
Let’s understand by looking example:
Let’s Checkout Scenario 1
public static void main(String[] args) {
Observable.range(1, 100)
.map(TestClass::new)
.subscribe(
item -> {
sleep(500);
System.out.println("Received: "+item.id);
});
}
static final class TestClass{
private final int id;
TestClass(int id){
this.id=id;
System.out.println("Constructing Object: "+id);
}
Note: even after delay we are getting result in sync manner, why?
Output:
Constructing Object: 1
Received: 1
Constructing Object: 2
Received: 2
Constructing Object: 3
Received: 3
Constructing Object: 4
Received: 4
Constructing Object: 5
Received: 5
Constructing Object: 5
Received: 5
Let’s Checkout Scenario 2
public static void main(String[] args) throws InterruptedException {
Observable.range(1, 10000000)
.map(TestClass::new).observeOn(Schedulers.io())
.subscribe(item -> { sleep(50);
System.out.println("Received: "+item.id);
});
sleep(Long.MAX_VALUE);
}
static final class TestClass{
private final int id;
TestClass(int id){
this.id=id;
System.out.println("Constructing Object: "+id);
}
}
Note: As you will see in output, consumer is unable to consume, so how to handle?
Flowables
Flowables will do all works for us.
We need to use Flowables interface instead of Observable.
Example: Flowables.range()
Just replace Observable.range() with Flowables.range()
Let’s look an example:
Understanding Flowables by Example
public static void main(String[] args) throws InterruptedException {
Flowable.range(1, 10000)
.map(TestClass::new)
.observeOn(Schedulers.io())
.subscribe(
item -> {
sleep(50);
System.out.println("Received: " + item.id);
});
sleep(Long.MAX_VALUE);
}
static final class TestClass {
final int id;
TestClass(int id) {
this.id = id;
System.out.println("Constructing object: " + id);
}
}
Once you will run this
code, you can observe
backpressure handling in
output console.
How to choose Flowable and Observable
When you expect only a flow in small stream of emission coming from source.
When you are dealing with large amount of data and performing complex operation on them.
When we will deal with synchronous data, so in that case we likely to use Observable.
when you start zipping and combining different streams on different threads, or use of
observeOn(), interval(),delay(), your apps in no longer synchronous, so for this case we likely to
use Flowable.
For button click, Android apps we do not have option to do programmatically, so in that case
we likely to use buffer, windows, throttling etc..
How to choose Flowable and Observable
When to source generate emission in regulated manner, especially true when the source in
asynchronous and push larger amount of data.
Network and Streaming APIs that can request a certain amount of returned results can easily be
back pressured as well.
Note: All the observable factories and operators are also applies in flowable.
Converting Observable to Flowable Example
public static void main(String[] args) throws InterruptedException {
Observable<Integer> observable = Observable.range(1, 100000);
observable.toFlowable(BackpressureStrategy.BUFFER).map(TestClass::new).observeOn(Schedulers.io())
.subscribe(
s -> {
sleep(50);
System.out.println("Received: " + s.id);
});
sleep(8000);
}
static final class TestClass {
private final int id;
TestClass(int id) {
this.id = id;
System.out.println("Constructing new Object: " + id);
}
}
Converting Flowable to Observable Example
public static void main(String[] args) throws InterruptedException {
Flowable<Integer> flowable = Flowable.range(1, 10000).observeOn(Schedulers.io());
flowable.toObservable().map(TestClass::new).subscribe(item -> {
sleep(50);
System.out.println("Received: " + item.id);
});
sleep(Long.MAX_VALUE);
}
static final class TestClass {
private final int id;
TestClass(int id) {
this.id = id;
MissingBackpressureException concept
● If we slowed down Flowable.interval(), our emissions would no longer reflect time intervals and become
misleading.
public static void main(String[] args) throws InterruptedException {
Flowable.interval(1, TimeUnit.MILLISECONDS) .observeOn(Schedulers.io()) .map(wait -> sleep(wait))
.subscribe(System.out::println,
Throwable::printStackTrace);
sleep(Long.MAX_VALUE);
}
private static <R> R sleep(R wait) throws InterruptedException {
Thread.sleep((Long) wait);
return wait;
}
Let’s checkout some Backpressure Operators
● onBackPressureBuffer
● onBackPressureLatest
● onBackPressureDrop
I think slide is going to be more than 100, so that’s why i am only demonstrating example
Let’s understand all backpressure by looking in example:
onBackPressureBuffer()
public static void main(String[] args) throws InterruptedException {
Flowable.interval(1, TimeUnit.MILLISECONDS)
.onBackpressureBuffer(10, () -> System.out.println("DROP!!!!! OverFlow"),
BackpressureOverflowStrategy.DROP_LATEST)
.observeOn(Schedulers.io())
.subscribe(item -> {
sleep(5);
System.out.println(item);
});
sleep(Long.MAX_VALUE);
}
onBackPressureLatest()
public static void main(String[] args) throws InterruptedException {
Flowable.interval(1, TimeUnit.MILLISECONDS)
.onBackpressureLatest()
.observeOn(Schedulers.io())
.subscribe(
i -> {
sleep(5);
System.out.println(i);
});
sleep(Long.MAX_VALUE);
}
onBackPressureDrop()
public static void main(String[] args) throws InterruptedException {
Flowable.interval(1, TimeUnit.MILLISECONDS)
.onBackpressureDrop(i -> System.out.println("Dropping " + i))
.observeOn(Schedulers.io())
.subscribe(i -> {
sleep(5);
System.out.println(i);
});
sleep(5000);
}
Multithreading
With these three API you can bring multithreading in your project, no synchronization, wait, notify, notifyall etc..
It is easiest way to bring multithreading in our applications..
● subscribeOn: Mechanism to add thread to our observable and subscribers.
● observeOn: It specifies on which scheduler the scubscriber should be notified.
● Schedulers: RxJava implements its own concurrency abstraction called Scheduler.
schedulers.io() : This scheduler is meant for I/O operations.like: db
schedulers.computation(): Default schedulers example: interval(), delay(), skip(), buffer() and user work etc..
schedulers.newThread(): It start new thread for the specified work.
Schedulers.form(Custom Thread Management -Executor Java): Custom
schedulers.immediate() and schedulers.trampoline()
Note: I am going to discuss more example on multithreading.
Let’s Look Simple Example
Taking two thread and running the task parallely.
Observable<String> green= Observable.just("A","B","C");
Observable<Integer> red= Observable.just(1,2,3);
green.subscribeOn(Schedulers.computation())
.map(s->sleepOneSec(s))
.subscribe(System.out::println);
red.subscribeOn(Schedulers.computation())
.map(s->sleepOneSec(s))
.subscribe(System.out::println);
Thread.sleep(20000); //just for blocking main thread.
private static <R> R sleepOneSec(R s) {
Thread.sleep(2000);
return s;
}
Output:
A
1
B
2
C
3
Note:It can be in any order
Zip in multithreading
Observable<String> green = Observable.just("A", "B", "C")
.subscribeOn(Schedulers.computation())
.map(s -> sleepOneSec(s));
Observable<Integer> red = Observable.just(1, 2, 3)
.subscribeOn(Schedulers.computation())
.map(s -> sleepOneSec(s));
Observable.zip(green,red,(g,r)->g+" -- "+r).subscribe(System.out::println);
Thread.sleep(8000); //to blocking main thread
private static <R> R sleepOneSec(R s) throws InterruptedException {
Thread.sleep(300);
return s;
Output:
A -- 1
B -- 2
C -- 3
Understanding subscribeOn()
Observable.just(1,2,3,4)
.subscribeOn(Schedulers.computation())
.map(s->s.hashCode())
.subscribe(s->System.out.println(Thread.currentThread().getName()+" - "+ s));
Observable.just(9,8,7,6)
.subscribeOn(Schedulers.computation())
.map(s->s.hashCode())
.subscribe(s->System.out.println(Thread.currentThread().getName()+" - "+ s));
Thread.sleep(2000);
Output:
RxComputationThreadPool-2 - 9
RxComputationThreadPool-1 - 2
RxComputationThreadPool-2 - 8
RxComputationThreadPool-1 - 3
RxComputationThreadPool-2 - 7
RxComputationThreadPool-2 - 6
RxComputationThreadPool-1 - 4
Each Observer getting its own thread
Observable<String> observable = Observable.just("hey", "man", "rxjava")
.subscribeOn(Schedulers.computation());
observable
.map(s -> s.toUpperCase())
.subscribe(s -> System.out.println(Thread.currentThread().getName() + "- " + s));
observable
.map(String::length)
.subscribe(s -> System.out.println(Thread.currentThread().getName() + "- " + s));
Thread.sleep(20000);
Output:
RxComputationThreadPool-1- HEY
RxComputationThreadPool-1- MAN
RxComputationThreadPool-2- 3
RxComputationThreadPool-2- 3
RxComputationThreadPool-2- 6
RxComputationThreadPool-1- RXJAVA
One Thread to Serve multiple Observer
Observable<String> observable =
Observable.just("hey", "man", "rxjava")
.subscribeOn(Schedulers.computation())
.publish()
.autoConnect(2);
Observable
.map(s->s.toUpperCase())
.subscribe(s->System.out.println(Thread.currentThread().getName()+"- "+s));
observable
.map(String::length)
.subscribe(s->System.out.println(Thread.currentThread().getName()+"- "+s));
Thread.sleep(5000);
Output:
RxComputationThreadPool-1- HEY
RxComputationThreadPool-1- 3
RxComputationThreadPool-1- MAN
RxComputationThreadPool-1- 3
RxComputationThreadPool-1- RXJAVA
RxComputationThreadPool-1- 6
How to make non-blocking call to API
public static void main(String[] args) throws InterruptedException {
Observable observable =
Observable.fromCallable(
() ->getResponse(
"http://samples.openweathermap.org/data/2.5/forecast?id=524901&appid=b1b15e88fa797225412429c1c50c122a1"))
.subscribeOn(Schedulers.io());
observable.subscribe(s -> System.out.println(Thread.currentThread().getName() + " = " + s));
doSomeThing();
doOtherTask();
}
private static void doOtherTask() {
System.out.println("Doing other task");
}
private static void doSomeThing() throws InterruptedException {
System.out.println("Excuting : " + Thread.currentThread().getName());
Thread.sleep(5000);
}
private static String getResponse(String path) {
try {
return new Scanner(new URL(path).openStream(), "UTF-8").useDelimiter("A").next();
} catch (Exception e) {
return e.getMessage();
}
}
Understanding observeOn()
Observable.just("WHISKEY/27653/TANGO", "6555/BRAVO", "232352/5675675/FOXTROT")
.subscribeOn(Schedulers.io())
.flatMap(s -> Observable.fromArray(s.split("/")))
.doOnNext(s ->System.out.println( "Split out " + s + " on thread " + Thread.currentThread().getName()))
.observeOn(Schedulers.computation())
.filter(s -> s.matches("[0-9]+"))
.map(Integer::valueOf)
.reduce((total, next) -> total + next)
.doOnSuccess( s ->System.out.println("Calculated sum " + s + " on thread " +
Thread.currentThread().getName()))
.observeOn(Schedulers.io())
.map(i -> i.toString())
.doOnSuccess(s ->System.out.println( "Printing " + s + " on thread " + Thread.currentThread().getName()))
.subscribe(s -> System.out.println(s));
We have changed io() thread to --->>> computation() and then to ---->>> io()
How ExecutorService can be used in RxJava
int numberOfThreadInPool=50;
ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreadInPool);
Scheduler schedulers = Schedulers.from(executorService);
Observable.just(1,2,3,4,5,6,7,8)
.subscribeOn(schedulers)
.doFinally(executorService::shutdown)
.subscribe(System.out::println);
Output:
1
2
3
…..
Reference
● http://www.reactivex.io
● https://github.com/ReactiveX/RxJava
● http://rxmarbles.com/
● BackPressure: https://github.com/ReactiveX/RxJava/wiki/Backpressure
● https://medium.com/netflix-techblog/reactive-programming-in-the-netflix-api-with-rxjava-
7811c3a1496a
● http://www.baeldung.com/tag/rxjava/
There are many source but I prefer to read book by “Tomasz Nurkiewicz, Ben Christensen”
Thanks! Enjoy
writing code in
reactive!
Too much slide,ohh!... Even after cutting to many things. That’s why I am
planning to record 3 to 4 hours video on RxJava.

More Related Content

ODP
Design Pattern - 2. Observer
Francesco Ierna
 
PDF
Observer Pattern
Akshat Vig
 
PPTX
Rxandroid
Thinh Thanh
 
PDF
Observer design pattern
Sameer Rathoud
 
PPSX
Observer design pattern
Sara Torkey
 
PPTX
Reactive Java (33rd Degree)
Tomasz Kowalczewski
 
PDF
Reactive programming with tracker
Designveloper
 
PDF
Saving lives with rx java
Shahar Barsheshet
 
Design Pattern - 2. Observer
Francesco Ierna
 
Observer Pattern
Akshat Vig
 
Rxandroid
Thinh Thanh
 
Observer design pattern
Sameer Rathoud
 
Observer design pattern
Sara Torkey
 
Reactive Java (33rd Degree)
Tomasz Kowalczewski
 
Reactive programming with tracker
Designveloper
 
Saving lives with rx java
Shahar Barsheshet
 

What's hot (18)

PDF
Building Scalable Stateless Applications with RxJava
Rick Warren
 
PPTX
Rx for Android & iOS by Harin Trivedi
harintrivedi
 
PDF
RxJava pour Android : présentation lors du GDG Android Montréal
Sidereo
 
PDF
Reactive programming with RxJava
Jobaer Chowdhury
 
PDF
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Nexus FrontierTech
 
PDF
Concurrent programming with RTOS
Sirin Software
 
KEY
openFrameworks 007 - events
roxlu
 
PPTX
Concurrent talk
rahulrevo
 
PDF
Introduction to Retrofit and RxJava
Fabio Collini
 
PDF
RxJava from the trenches
Peter Hendriks
 
PPTX
RxJS In-Depth - AngularConnect 2015
Ben Lesh
 
PDF
Evolutionary Testing for Crash Reproduction
Annibale Panichella
 
PDF
WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)
DataStax Academy
 
PPTX
Rx java in action
Pratama Nur Wijaya
 
PDF
Microsoft word java
Ravi Purohit
 
PPTX
Reactive Extensions: classic Observer in .NET
EPAM
 
PDF
Art of unit testing: How developer should care about code quality
Dmytro Patserkovskyi
 
PPTX
Reactive Programming no Android
Guilherme Branco
 
Building Scalable Stateless Applications with RxJava
Rick Warren
 
Rx for Android & iOS by Harin Trivedi
harintrivedi
 
RxJava pour Android : présentation lors du GDG Android Montréal
Sidereo
 
Reactive programming with RxJava
Jobaer Chowdhury
 
Tech Talk #4 : RxJava and Using RxJava in MVP - Dương Văn Tới
Nexus FrontierTech
 
Concurrent programming with RTOS
Sirin Software
 
openFrameworks 007 - events
roxlu
 
Concurrent talk
rahulrevo
 
Introduction to Retrofit and RxJava
Fabio Collini
 
RxJava from the trenches
Peter Hendriks
 
RxJS In-Depth - AngularConnect 2015
Ben Lesh
 
Evolutionary Testing for Crash Reproduction
Annibale Panichella
 
WattGo: Analyses temps-réél de series temporelles avec Spark et Solr (Français)
DataStax Academy
 
Rx java in action
Pratama Nur Wijaya
 
Microsoft word java
Ravi Purohit
 
Reactive Extensions: classic Observer in .NET
EPAM
 
Art of unit testing: How developer should care about code quality
Dmytro Patserkovskyi
 
Reactive Programming no Android
Guilherme Branco
 
Ad

Similar to RxJava 2 Reactive extensions for the JVM (20)

PDF
Intro to Rx Java
Syed Awais Mazhar Bukhari
 
PPTX
RxAndroid
Thinh Thanh
 
PPTX
Reactive programming with RxAndroid
Savvycom Savvycom
 
PPTX
An Introduction to RxJava
Sanjay Acharya
 
PPTX
Introduction to RxJava on Android
Chris Arriola
 
PDF
Reactive java - Reactive Programming + RxJava
NexThoughts Technologies
 
PPTX
RxJava2 Slides
YarikS
 
PPTX
Intro to Functional Programming with RxJava
Mike Nakhimovich
 
PDF
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Codemotion
 
PDF
Reactive Programming for a demanding world: building event-driven and respons...
Mario Fusco
 
PDF
RxJava for Android - GDG DevFest Ukraine 2015
Constantine Mars
 
PPTX
Intro to Reactive Thinking and RxJava 2
JollyRogers5
 
PDF
Streams, Streams Everywhere! An Introduction to Rx
Andrzej Sitek
 
PDF
How to Think in RxJava Before Reacting
IndicThreads
 
PPTX
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
 
PDF
RxJava@DAUG
Maxim Volgin
 
PDF
RxJava - introduction & design
allegro.tech
 
PDF
The Mayans Lost Guide to RxJava on Android
Fernando Cejas
 
PPTX
Reactive programming with rx java
CongTrung Vnit
 
PPTX
Reactive Programming in Java 8 with Rx-Java
Kasun Indrasiri
 
Intro to Rx Java
Syed Awais Mazhar Bukhari
 
RxAndroid
Thinh Thanh
 
Reactive programming with RxAndroid
Savvycom Savvycom
 
An Introduction to RxJava
Sanjay Acharya
 
Introduction to RxJava on Android
Chris Arriola
 
Reactive java - Reactive Programming + RxJava
NexThoughts Technologies
 
RxJava2 Slides
YarikS
 
Intro to Functional Programming with RxJava
Mike Nakhimovich
 
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Codemotion
 
Reactive Programming for a demanding world: building event-driven and respons...
Mario Fusco
 
RxJava for Android - GDG DevFest Ukraine 2015
Constantine Mars
 
Intro to Reactive Thinking and RxJava 2
JollyRogers5
 
Streams, Streams Everywhere! An Introduction to Rx
Andrzej Sitek
 
How to Think in RxJava Before Reacting
IndicThreads
 
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
 
RxJava@DAUG
Maxim Volgin
 
RxJava - introduction & design
allegro.tech
 
The Mayans Lost Guide to RxJava on Android
Fernando Cejas
 
Reactive programming with rx java
CongTrung Vnit
 
Reactive Programming in Java 8 with Rx-Java
Kasun Indrasiri
 
Ad

Recently uploaded (20)

PDF
BRKDCN-2613.pdf Cisco AI DC NVIDIA presentation
demidovs1
 
PDF
Chad Ayach - A Versatile Aerospace Professional
Chad Ayach
 
PDF
6th International Conference on Artificial Intelligence and Machine Learning ...
gerogepatton
 
PPTX
Victory Precisions_Supplier Profile.pptx
victoryprecisions199
 
PDF
5 Influence line.pdf for structural engineers
Endalkazene
 
PDF
B.Tech Data Science Program (Industry Integrated ) Syllabus
rvray078
 
PDF
A Framework for Securing Personal Data Shared by Users on the Digital Platforms
ijcncjournal019
 
PPTX
Simulation of electric circuit laws using tinkercad.pptx
VidhyaH3
 
PPTX
Edge to Cloud Protocol HTTP WEBSOCKET MQTT-SN MQTT.pptx
dhanashri894551
 
PDF
Unit I Part II.pdf : Security Fundamentals
Dr. Madhuri Jawale
 
PDF
2010_Book_EnvironmentalBioengineering (1).pdf
EmilianoRodriguezTll
 
PPTX
Production of bioplastic from fruit peels.pptx
alwingeorgealwingeor
 
PPT
SCOPE_~1- technology of green house and poyhouse
bala464780
 
PDF
FLEX-LNG-Company-Presentation-Nov-2017.pdf
jbloggzs
 
PDF
July 2025: Top 10 Read Articles Advanced Information Technology
ijait
 
PPTX
TE-AI-Unit VI notes using planning model
swatigaikwad6389
 
PDF
flutter Launcher Icons, Splash Screens & Fonts
Ahmed Mohamed
 
PDF
settlement FOR FOUNDATION ENGINEERS.pdf
Endalkazene
 
PDF
EVS+PRESENTATIONS EVS+PRESENTATIONS like
saiyedaqib429
 
PDF
Traditional Exams vs Continuous Assessment in Boarding Schools.pdf
The Asian School
 
BRKDCN-2613.pdf Cisco AI DC NVIDIA presentation
demidovs1
 
Chad Ayach - A Versatile Aerospace Professional
Chad Ayach
 
6th International Conference on Artificial Intelligence and Machine Learning ...
gerogepatton
 
Victory Precisions_Supplier Profile.pptx
victoryprecisions199
 
5 Influence line.pdf for structural engineers
Endalkazene
 
B.Tech Data Science Program (Industry Integrated ) Syllabus
rvray078
 
A Framework for Securing Personal Data Shared by Users on the Digital Platforms
ijcncjournal019
 
Simulation of electric circuit laws using tinkercad.pptx
VidhyaH3
 
Edge to Cloud Protocol HTTP WEBSOCKET MQTT-SN MQTT.pptx
dhanashri894551
 
Unit I Part II.pdf : Security Fundamentals
Dr. Madhuri Jawale
 
2010_Book_EnvironmentalBioengineering (1).pdf
EmilianoRodriguezTll
 
Production of bioplastic from fruit peels.pptx
alwingeorgealwingeor
 
SCOPE_~1- technology of green house and poyhouse
bala464780
 
FLEX-LNG-Company-Presentation-Nov-2017.pdf
jbloggzs
 
July 2025: Top 10 Read Articles Advanced Information Technology
ijait
 
TE-AI-Unit VI notes using planning model
swatigaikwad6389
 
flutter Launcher Icons, Splash Screens & Fonts
Ahmed Mohamed
 
settlement FOR FOUNDATION ENGINEERS.pdf
Endalkazene
 
EVS+PRESENTATIONS EVS+PRESENTATIONS like
saiyedaqib429
 
Traditional Exams vs Continuous Assessment in Boarding Schools.pdf
The Asian School
 

RxJava 2 Reactive extensions for the JVM

  • 1. RxJava 2 : Reactive Extensions for the JVM NETESH KUMAR Senior Software Engineer @ Informatica 12/06/2018
  • 2. Why RxJava ? Why should I Learn new Programming paradigms ? ● Users expect real time data. ● Users want their tweets now. ● Users want to see their order confirmed now. ● Users need prices accurate as of now. ● Online games need to be responsive. ● As a developer, you demand fire-and-forget messaging. ● You don't want to be blocked waiting for a result. ● You want to have the result pushed to you when it is ready. ● Even better, when working with result sets, you want to receive individual results as they are ready. ● You do not want to wait for the entire set to be processed before you see the first row. The world has moved to push; There are hell lot of reason.
  • 3. Reactive Programming A library for Composing Asynchronous and Event Based program using Observable Sequences for the Java Virtual Machine. Wikipedia:- reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. Example: A B C fun add(A,B){ return A+B;} 9 4 13
  • 4. What is Rx in RxJava Java VM implementation of An Api for asynchronous programming with Observable streams. ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming A Observable pattern is extended version or combination of Observer and Iterable Design pattern.
  • 5. Observer & Iterable Design Pattern Observer Design Pattern: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Iterator Design Pattern: Provides a way to access the elements of an aggregate object without exposing its underlying representation. Missing in Observer: ● The ability for the producer to signal to the consumer that there is no more data available. ● The ability for the producer to signal to the consumer that an error has occurred.
  • 6. Reactive Principles The Reactive Manifesto: Let’s look one by one each in next slide
  • 7. The Reactive Manifesto Responsive: a reactive system needs to handle requests in a reasonable time (I let you define reasonable). Resilient: a reactive system must stay responsive in the face of failures (crash, timeout, 500 error ), so it must be designed for failures and deal with them appropriately. Elastic: a reactive system must stay responsive under various loads. Consequently, it must scale up and down, and be able to handle the load with minimal resources. Message driven: components from a reactive system interacts using asynchronous message passing.
  • 8. Build blocks for RxJava A set of methods for modifying and composing the data. OBSERVABLES representing sources of data. SUBSCRIBERS or OBSERVERS listening to the OBSERVABLES. SCHEDULERS Source Consumer OBSERVABLE SUBSCRIBER onNext( ) onCompleted( ) onError( )
  • 10. Application of RxJava Client Side Example: Thread switching, event handling and more. Server Side Example: Request Response Microservice A Microservice B Microservice C Business Logic
  • 11. Types Of Observables In RxJava Observable — Operator — Observer Observable Operator Observer
  • 12. Different Types of Observables and Observers OBSERVABLES OBSERVERS ● Observable ● Flowable ● Single ● Maybe ● Completable ● Observer ● SingleObserver ● MaybeObserver ● CompletableObserver Let’s look all Observable and Observer in details:-
  • 13. Observable <> Observer It is the simplest Observable which can emit more than one value. use-case: Let’s say you are downloading something and you have to push the status of download percentage. Example: Observable<String> observable = Observable.just(“A”,”B”,”C”).subscribe(System.out::println); Output: A B C
  • 14. Flowable <> Observer Use-case: Flowable comes to picture when there is a case that the Observable is emitting huge numbers of values which can’t be consumed by the Observer. In this case, the Observable needs to skip some values on the basis of some strategy else it will throw an exception. The Flowable Observable handles the exception with a strategy. The strategy is called BackPressureStrategy and the exception is called MissingBackPressureException. Go to BackPressure Slide
  • 15. Single <> Single Observer Use-case: Single is used when the Observable has to emit only one value like a response from a network call. Example: Single.just("Hello").subscribe(System.out::println,Throwable::printStackTrace); Observable observable = Observable.just("A","B","C"); observable.first("Nil").subscribe(System.out::println); Output: Hello A
  • 16. Maybe <> Maybe Observer Use-case: Maybe is used when the Observable has to emit a value or no value. Example: Maybe<String> maybe = Maybe.just("Hi"); maybe.subscribe(System.out::println); Maybe<String> maybe_two = Maybe.empty(); maybe_two.subscribe(System.out::println); Output: Hi
  • 17. Completable <> Completable Observer Use-case: Completable is used when the Observable has to do some task without emitting a value. Example: private static void running() { System.out.println("I am doing some task!"); } Completable.fromRunnable(()->running()).subscribe(()->System.out.println("Done!")); Output: I am doing some task! Done!
  • 18. Cold vs Hot vs Multicasting Observable There are subtle behaviors in a relationship between an Observable and an Observer depending on how the Observable is implemented.
  • 19. Cold Observables Cold Observables will replay the emissions to each Observer, ensuring that all Observers get all the data. Real Time Examples: Cold Observables are much like a pendrive or CD player, that can be replayed to each listener, so each person can hear all the tracks at any time. Will have Demo in coming slide
  • 20. Hot Observable If an Observer subscribes to a hot Observable, receives some emissions, and then another Observer comes in afterwards, that second Observer will have missed those emissions. Real Time Example: A hot Observable is more like a radio or tv station. It broadcasts the same emissions to all Observers at the same time.
  • 21. Connectable or Multicasting Observable A helpful form of hot Observable is ConnectableObservable. It will take any Observable, even if it is cold, and make it hot so that all emissions are played to all Observers at once. To make it:- just add publish() to any observable. And add observable.connect() to start firing the emissions. ConnectableObservable<String> observable=Observable.just(Alpha","Beta","Gamma").publish(); observable.subscribe(System.out::println); observable.subscribe(System.out::println); observable.connect(); Let’s se few image to understand it better, like what all we can do.
  • 22. It’s self-explanatory, so explaining in ppt. If you want to look code, find in my github
  • 23. Creating Observable :- with just() Observable.just("Hello") - Allows to create an observable as wrapper around other data types Observable<String> observable = Observable.just(“a”, “b”, “c”, “d”, “e”); Subscriber<String> my_subscriber = Subscribers.create( n->System.out.println(n); e->System.out.println(“Error ”+e); ()->System.out.println(“Completed); ); observable.subscribe(my_subscriber); Can be written like: Observable<String> observable = Observable.just(“a”, “b”, “c”, “d”, “e”).subscribe(System.out::prinltn); Output: a b c d e Completed
  • 24. Creating Observable :- with create() Observable<String> observable = Observable.create(emitter -> { try { List<String> todos = getTodos(); for (String todo : todos) { emitter.onNext(todo); } emitter.onComplete(); } catch (Exception e) { emitter.onError(e); } }); observable.subscribe(s->System.out.println(s), Throwable::printStackTrace); Can be written : Disposable disposable = observable .subscribe(t -> System.out.print(t),e -> e.printStackTrace()); disposable.dispose(); getTodos=[“a”,”b”,”c”] Output: a b c
  • 25. Creating Observable :- with fromArray() Observable.fromArray() - takes an array and emits their values in their order in the data structure List<Integer> list = Arrays.asList(1,2,3,4,5); Observable<List<Integer>> observable = Observable.fromArray(list); observable.subscribe(System.out::println); Output: [1,2,3,4,5]
  • 26. Creating Observable :- with fromIterable() Observable.fromIterable() - takes an java.lang.Iterable<T> and emits their values in their order in the data structure List<Integer> list = Arrays.asList(1,2,3,4,5); Observable<Integer> observable = Observable.fromIterable(list); observable.subscribe(System.out::println); Output: 1 2 3 4 5
  • 27. Creating Observable :- with fromCallable() Observable.fromCallable() is great for converting a single function into an Observable. Method -> getStudentName() Observable.fromCallable(new Callable<Object>() { @Override public Object call() throws Exception { return getStudentInfo(); } }).subscribe(System.out::println); Can be written like: Observable.fromCallable(()->getStudentName()).subscribe(System.out::println);
  • 28. Creating Observable :- with fromFuture() Observable.fromFuture() - Allows to create an observable for a java.util.concurrent.Future if we have existing libraries that yield Futures, you can easily turn them into Observables via Observable.future(). Example:- Future<String> futureValue = ...; Observable.fromFuture(futureValue).subscribe(System.out::println);
  • 29. Creating Observable :- with range() Observable.range():-Returns an Observable that emits a sequence of Integers within a specified range Int start = 1; int count = 5; Observable observable = Observable.range(start,count).subscribe(System.out::println); Output: 1 2 3 4 5
  • 30. Creating Observable :- with interval() Observable.interval() - An observable that emits Long objects in a given interval Observable observable = Observable.interval(3, TimeUnit.SECONDS); observable.subscribe(System.out::println); sleep(5000); Output: 0 1 2 3, 4
  • 31. Creating Observable :- with empty() Observable.empty(): For creating empty stream. Observable.never(): This is same as empty(), except one minor difference. It will never terminate or get called onComplete() method. Observable.error(): will only get used for testing. Observable<String> empty = Observable.empty(); empty.subscribe( System.out::println, Throwable::printStackTrace, () -> System.out.println("Done!") ); Output: Done!
  • 32. Creating Observable :- with defer() Observable.defer(): is ability to create a separate state for each Observer.if your source is stateful and you want to create a separate state for each Observer. Int start=1;int count=3; Observable<Integer> source = Observable.defer(() -> Observable.range(start,count)); source.subscribe(System.out::println); count=5; source.subscribe(System.out::println); Output: 1 2 3 1 2 3 4 5
  • 33. Operators Operators applies in between source and destination. Observable Subscriber Operator 1 Operator 2 Operator n
  • 34. Operators By Category Type of Operators: Creating Observables Conditional and Boolean Operators Transforming Observables Mathematical and Aggregate Operators Filtering Observables Backpressure Operators Combining Observables Connectable Observable Operators Error Handling Operators Operators to Convert Observables Observable Utility Operators Let’s look some of them...
  • 35. Skip() Skip: Suppress the first n items emitted by an Observable. Example: Observable<Integer> observable = Observable.range(1,100); observable.skip(95).subscribe(System.out::println); Output: 96 97 98 99 100
  • 36. Filtering Observables There are many filtering option available in rxjava, let’s see few example out of them. ● Debounce — only emit an item from an Observable if a particular timespan has passed without it emitting another item. ● Distinct — suppress duplicate items emitted by an Observable. ● ElementAt — emit only item n emitted by an Observable. ● Filter — emit only those items from an Observable that pass a predicate test. ● First — emit only the first item, or the first item that meets a condition, from an Observable. ● IgnoreElements — do not emit any items from an Observable but mirror its termination notification. ● Last — emit only the last item emitted by an Observable. ● Sample — emit the most recent item emitted by an Observable within periodic time intervals. ● Skip — suppress the first n items emitted by an Observable. ● SkipLast — suppress the last n items emitted by an Observable. ● Take — emit only the first n items emitted by an Observable. ● TakeLast — emit only the last n items emitted by an Observable.
  • 37. filter() Filter: Emit only those items from an Observable that pass a predicate test Example: Observable<Integer> observable = Observable.just(1,4,3,2,6,7,9,13,14,32); observable.filter(i- >i%2==0).subscribe(System.out::println); Output: 4 2 6 14 32
  • 38. DistinctUntilChanged() DistinctUntilChanged: The distinctUntilChanged() function will ignore duplicate consecutive emissions. Look rxmarbles: http://www.rxmarbles.com/#distinctUntilChanged Example: Observable<Integer> observable = Observable.just(1,1,2,2,3,1,1,2); observable.distinctUntilChanged().subscribe(System.out::println); Output: 1 2 3 1 2
  • 39. Transforming Observables Operators that transform items that are emitted by an Observable. Buffer — periodically gather items from an Observable into bundles and emit these bundles rather than emitting the items one at a time FlatMap — transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable GroupBy — divide an Observable into a set of Observables that each emit a different group of items from the original Observable, organized by key Map — transform the items emitted by an Observable by applying a function to each item Scan — apply a function to each item emitted by an Observable, sequentially, and emit each successive value Window — periodically subdivide items from an Observable into Observable windows and emit these windows rather than emitting the items one at a time
  • 40. Let’s Understand flatMap() It performs a dynamic Observable.merge() by taking each emission and maps into in Observable. Note: It doesn’t maintain order, for maintaining order you can user concatMap(). Let’s Understand by looking in example.
  • 41. flatMap() Example Let’s Say I have Number/Special character and String, Now we want to make observable of only Number. So here is perfect example. Observable<String> observable = Observable.just( "521934/2342/FOXTROT", "21962/12112/78886/TANGO", "283242/4542/WHISKEY/2348562"); observable .flatMap(s -> Observable.fromArray(s.split("/"))) .filter(s -> s.matches("[0-9]+")) .map(Integer::valueOf) .subscribe(System.out::println); Output: 521934 2342 21962 12112 78886 283242 4542 2348562
  • 42. Let’s Understand groupBy() It’s similar operator like SQL, even much more. Can be grouped by key, value etc… Let’s Understand by looking in example:
  • 43. groupBy() Example Observable<String> observable = Observable.just("Alpha", "Beta", "Gamma", "Delta", "Epsilon"); Observable<GroupedObservable<Integer,String>> groupedObservableObservable = observable.groupBy(String::length); groupedObservableObservable.flatMapSingle(s -> s.toList()).subscribe(System.out::println); Output: [Beta] [Alpha, Gamma, Delta] [Epsilon]
  • 44. Combining Observables Operators that work with multiple source Observables to create a single Observable And/Then/When — combine sets of items emitted by two or more Observables by means of Pattern and Plan intermediaries CombineLatest — when an item is emitted by either of two Observables, combine the latest item emitted by each Observable via a specified function and emit items based on the results of this function Join — combine items emitted by two Observables whenever an item from one Observable is emitted during a time window defined according to an item emitted by the other Observable Merge — combine multiple Observables into one by merging their emissions StartsWith — emit a specified sequence of items before beginning to emit the items from the source Observable Switch — convert an Observable that emits Observables into a single Observable that emits the items emitted by the most-recently-emitted of those Observables Zip — combine the emissions of multiple Observables together via a specified function and emit single items for each combination based on the results of this function
  • 45. Let’s Understand merger() using Diagram The Observable.merge() operator will take two or more Observable<T> sources emitting the same type T and then consolidate them into a single Observable<T> Note: merge() and mergerWith(): doesn't give order guarantee. concat(): It’s give guarantee.
  • 46. Understanding merge() by Example Observable<String> observable = Observable.just("A","B","C"); Observable<String> observable2 = Observable.just("A1","B1","C1"); Observable.merge(observable,observable2).subscribe(System.out::println); Output: A B C A1 B1 C1 As you can see output comes in order but it’s not guarantee. Note: you can create a list of observable array and pass it to Observable.mergeArray(list).
  • 47. Understanding concat() using Diagram Concat: emit the emissions from two or more Observables without interleaving them
  • 48. Understanding zip() Zip: It takes an emission from each Observable source and combine it into a single emission Note: Observable can emit different type.
  • 49. Understanding zip() using Example Observable<String> observable = Observable.just("Bahubali","Singham"); Observable<Integer> observable1 = Observable.range(1,10); Observable.zip(observable,observable1,(s,i)-> s+" - "+i).subscribe(System.out::println); Output: Bahubali - 1 Singham - 2 There are bunch of operator available in rxjava.
  • 50. Error Handling Operators Operators that help to recover from error notifications from an Observable Catch — recover from an onError notification by continuing the sequence without error Retry — if a source Observable sends an onError notification, resubscribe to it in the hopes that it will complete without error onErrorReturnand or onErrorReturnItem -For resort to a default value when an exception occurs onErrorResumeNext- similar to onErrorReturned but accepts another Observable as a parameter to emit potentially multiple values
  • 51. Handling Errors in Rxjava Let’s take common example: dividing number by 0. If you do not catch exception then your program terminate.Am I right huh? Same case with RxJava but little change, let’s understand via example: Observable<Integer> observable = Observable.just(4,2,0,3,7,6); observable.map(i->10/i).subscribe(s->System.out.println(s),e->System.out.println(e)); Output: 2 5 java.lang.ArithmeticException: / by zero Looks cool: But how to return default value instead of error or how to retry again and again. Let’s discuss in another slide.
  • 52. onErrorReturn() and onErrorReturnItem() Let’s understand by example: Observable<Integer> observable = Observable.just(4,2,0,3,7,6); observable.map(i->10/i).onErrorReturnItem(-1).subscribe(System.out::println); observable.map(i->10/i).onErrorReturn(e->-1).subscribe(s->System.out.println(s),e- >System.out.println(e)); Output: 2 5 -1
  • 53. onErrorResumeNext() Let’s understand by example: Observable<Integer> observable = Observable.just(4,2,0,3,7,6); observable.map(i->10/i).onErrorResumeNext(Observable.just(-1).repeat(3)).subscribe( s->System.out.println(s), e->System.out.println(e) ); Output: 2 5 -1 -1 -1
  • 54. retry() Another way of recovery is retry(). Let’s understand by example: Observable<Integer> observable = Observable.just(4,2,0,3,7,6); observable.map(i->10/i).retry(2).subscribe(s->System.out.println(s),e->System.out.println(e)); It will retry two time because we have mention in argument. Output: 2 5 2 5 java.lang.ArithmeticException: / by zero
  • 55. Conditional and Boolean Operators Operators that evaluate one or more Observables or items emitted by Observables All — determine whether all items emitted by an Observable meet some criteria Amb — given two or more source Observables, emit all of the items from only the first of these Observables to emit an item Contains — determine whether an Observable emits a particular item or not DefaultIfEmpty — emit items from the source Observable, or a default item if the source Observable emits nothing SequenceEqual — determine whether two Observables emit the same sequence of items SkipUntil — discard items emitted by an Observable until a second Observable emits an item SkipWhile — discard items emitted by an Observable until a specified condition becomes false TakeUntil — discard items emitted by an Observable after a second Observable emits an item or terminates TakeWhile — discard items emitted by an Observable after a specified condition becomes false
  • 56. Ambiguous Ambiguous: when you have multiple sources for the same data or events and you want the fastest one to win. Let’s say we have two server (ServerA and ServerB) any of then can give me response. Now customer made a request for data, whoever gives me data first, we will accept data from that server.(I am talking in terms of Observable) Api will look like: Observable.amb(“can pass list or two observable).subscribe(System.out::println);
  • 57. Mathematical and Aggregate Operators It’s simple to use mathematical operator, not covering in ppt. If you want to find the code for all, please visit my github page.s Operators that operate on the entire sequence of items emitted by an Observable Average — calculates the average of numbers emitted by an Observable and emits this average Concat — emit the emissions from two or more Observables without interleaving them Count — count the number of items emitted by the source Observable and emit only this value Max — determine, and emit, the maximum-valued item emitted by an Observable Min — determine, and emit, the minimum-valued item emitted by an Observable Reduce — apply a function to each item emitted by an Observable, sequentially, and emit the final value Sum — calculate the sum of numbers emitted by an Observable and emit this sum
  • 58. Action Operators Apply these operator for getting visibility into an Observable chain ● doOnNext(), doOnComplete() and doOnError() ● doOnSubscibe(), doOnDispose() and doOnSuccess() All are pretty simple, I won’t discuss all, let me take one example and show you. Observable<Integer> observable = Observable.just(4,2,0,3,7,6); observable.doOnNext(s->System.out.println("Processing:"+s)) .map(i->10/i).subscribe(s->System.out.println(s),e->System.out.println(e)); Output: Processing:4 2 Processing:2 5 Processing:0 java.lang.ArithmeticException: / by zero
  • 59. Types of Subject in RxJava Subject: A Subject is a sort of bridge or proxy that is available in some implementations of ReactiveX that acts both as an observer and as an Observable. Because it is an observer, it can subscribe to one or more Observables, and because it is an Observable, it can pass through the items it observes by re-emitting them, and it can also emit new items. ● PublishSubject ● ReplaySubject ● BehaviorSubject ● AsyncSubject
  • 60. PublishSubject PublishSubject emits to an observer only those items that are emitted by the source Observable(s) subsequent to the time of the subscription. Use-case: if a student entered late into the classroom, he just wants to listen from that point of time when he entered the classroom, PublishSubject will be best choice.
  • 61. ReplaySubject ReplaySubject: It emits all the items of the source Observable, regardless of when the subscriber subscribes. Use-case: if a student entered late into the classroom, he wants to listen from the beginning.
  • 62. BehaviorSubject BehaviorSubject: It emits the most recently emitted item and all the subsequent items of the source Observable when an observer subscribes to it. Use-case: if a student entered late into the classroom, he wants to listen the most recent things(not from the beginning) being taught by the professor so that he gets the idea of the context.
  • 63. AsyncSubject AsyncSubject: It only emits the last value of the source Observable(and only the last value) Use-case: if a student entered at any point of time into the classroom, and he wants to listen only about the last thing(and only the last thing) being taught
  • 64. Disposable in RxJava It is use for unsubscribe from source (observable). This also used for avoid memory leak. Let’s take some real problem and try to solve: Use-case: An Application do many operation in background, and many time can happen that background task is no longer need, in that situation we must have a way to unsubscribe from source. Example: when you start some task, and you forgot to stop, in that case you can get memory leak. So to avoid memory leak we can use disposable. clear() will clear all, but can accept new disposable. dispose() will clear all and set isDisposed = true, so it will not accept any new disposable.
  • 65. Handling subscriber with Disposable Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS); Disposable disposable = observable.subscribe(System.out::println); Thread.sleep(5000); disposable.dispose(); Thread.sleep(5000); Output: 0 1 2 3 After dispose() it will not print any result. What if multiple subscriber listening to observable ?
  • 66. Handling multiple subscriber with Disposable To handle multiple subscriber we have compositedisposable() in rxjava. Let’s see how? Step 1: create composite disposable Step 2: Add all disposable to composite disposable Step 3: call dispose() method. Example: private static final CompositeDisposable disposables = new CompositeDisposable(); Observable<Long> seconds = Observable.interval(1, TimeUnit.SECONDS); Disposable disposable1 = seconds.subscribe(l -> System.out.println("Observer 1: " + l)); Disposable disposable2 = seconds.subscribe(l -> System.out.println("Observer 2: " + l)); disposables.addAll(disposable1, disposable2); sleep(5000); disposables.dispose(); sleep(5000);
  • 67. Handle rapidly fired emission in RxJava Let’s checkout some operators that help rapidly firing sources without using back pressure and are especially appropriate for situations where backpressure cannot be utilized. ● Buffering ● Windowing ● Throttling ● Switching
  • 68. Understanding buffer() in RxJava It emit each batch as a list or another collection type. buffer() operator will gather emissions within a certain scope, like list,map etc… example: fixed-size buffering time-based buffering boundary-based buffering Let’s understand by looking in example.
  • 69. Understanding fixed size buffer using Example This is the best example for sending data in chunk. Observable.range(1,36).buffer(10).subscribe(System.out::println); Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] [21, 22, 23, 24, 25, 26, 27, 28, 29, 30] [31, 32, 33, 34, 35, 36]
  • 70. Understanding time based buffer using Example Observable.interval(1, TimeUnit.SECONDS) .map(s->s+100) .buffer(3,TimeUnit.SECONDS) .subscribe(System.out::println); sleep(9000); Output: [100, 101] [102, 103, 104, 105] [106, 107]
  • 71. Understanding boundary-based buffer using Example It accept another Observable as a boundary argument. It does not matter what type this other Observable emits. Observable<Long> boundary = Observable.interval(1,TimeUnit.SECONDS); Observable.interval(300,TimeUnit.MILLISECONDS).buffer(boundary).subscribe(System.out::pr intln); Output: [0, 1, 2] [3, 4, 5] [6, 7, 8] [9, 10, 11, 12] [13, 14, 15] [16, 17, 18, 19]
  • 72. Understanding window() in RxJava window() is similar to buffer, except it emits in other observable rather than collections. Let’s understand by looking example
  • 73. Understanding window() using Example Fixed-size Example: Observable.range(1,50).window(5) .flatMapSingle(s->s.toList()) .subscribe(System.out::println); Output: [1, 2, 3, 4, 5] [6, 7, 8, 9, 10] [11, 12, 13, 14, 15] [16, 17, 18] Time-Based Example: Observable.interval(1, TimeUnit.MILLISECONDS) .map(i->i+100) .window(1,TimeUnit.SECONDS) .flatMapSingle(s->s.toList()) .subscribe(System.out::println); Boundary-Based Example: It’s is similar to boundary-based buffer.
  • 74. Understanding throttling() in RxJava buffer() and windows() batch up source emission into collection or observable. But throttle() omits emission when emission occur rapidly. Use-case: if user click on button rapidly throttleLast()/ sample() throttleFirst() throttleWithTimeout/ debounce()
  • 75. Understanding throttleLast() using Example Observable.interval(100, TimeUnit.MILLISECONDS).take(7).subscribe(s->System.out.println(" source 1: "+s)); Observable.interval(400, TimeUnit.MILLISECONDS).take(3).subscribe(s->System.out.println(" source 2: "+s)); Observable.interval(900, TimeUnit.MILLISECONDS).take(2).subscribe(s->System.out.println(" source 3: "+s)); Output: source 1: 0 source 1: 1 source 1: 2 source 1: 3 source 2: 0 source 1: 4 source 1: 5 source 1: 6 source 2: 1 source 3: 0 source 2: 2 source 3: 1 Let’s check, How to apply throttleLast(). Observable.concat(source1,source2,source3).throttleLast(1,TimeUnit.SECONDS).subsc ribe(s->System.out.println(" source : "+s)); Output: source : 6 source : 2 source : 0 source : 1 Note: throttleFirst() is similar to throttleLast(), so not covering.
  • 76. Understanding switching() in Rxjava SwitchMap: SwitchMap would emit only the latest observable after a particular delay. It ignores all the previous ones. It is useful when it comes to retrieving the latest data from a feed. It’s useful when you need to identify the latest among many feeds.
  • 77. Backpressure in RxJava Backpressure relates to a mechanism through which the subscriber can signal to the producer how much data it can consume and so to produce only that amount. When a source is emitting more items rapidly than an operator or subscriber can consume them, then the item that are overflowing from publisher need to be handled. Let’s understand by looking example:
  • 78. Let’s Checkout Scenario 1 public static void main(String[] args) { Observable.range(1, 100) .map(TestClass::new) .subscribe( item -> { sleep(500); System.out.println("Received: "+item.id); }); } static final class TestClass{ private final int id; TestClass(int id){ this.id=id; System.out.println("Constructing Object: "+id); } Note: even after delay we are getting result in sync manner, why? Output: Constructing Object: 1 Received: 1 Constructing Object: 2 Received: 2 Constructing Object: 3 Received: 3 Constructing Object: 4 Received: 4 Constructing Object: 5 Received: 5 Constructing Object: 5 Received: 5
  • 79. Let’s Checkout Scenario 2 public static void main(String[] args) throws InterruptedException { Observable.range(1, 10000000) .map(TestClass::new).observeOn(Schedulers.io()) .subscribe(item -> { sleep(50); System.out.println("Received: "+item.id); }); sleep(Long.MAX_VALUE); } static final class TestClass{ private final int id; TestClass(int id){ this.id=id; System.out.println("Constructing Object: "+id); } } Note: As you will see in output, consumer is unable to consume, so how to handle?
  • 80. Flowables Flowables will do all works for us. We need to use Flowables interface instead of Observable. Example: Flowables.range() Just replace Observable.range() with Flowables.range() Let’s look an example:
  • 81. Understanding Flowables by Example public static void main(String[] args) throws InterruptedException { Flowable.range(1, 10000) .map(TestClass::new) .observeOn(Schedulers.io()) .subscribe( item -> { sleep(50); System.out.println("Received: " + item.id); }); sleep(Long.MAX_VALUE); } static final class TestClass { final int id; TestClass(int id) { this.id = id; System.out.println("Constructing object: " + id); } } Once you will run this code, you can observe backpressure handling in output console.
  • 82. How to choose Flowable and Observable When you expect only a flow in small stream of emission coming from source. When you are dealing with large amount of data and performing complex operation on them. When we will deal with synchronous data, so in that case we likely to use Observable. when you start zipping and combining different streams on different threads, or use of observeOn(), interval(),delay(), your apps in no longer synchronous, so for this case we likely to use Flowable. For button click, Android apps we do not have option to do programmatically, so in that case we likely to use buffer, windows, throttling etc..
  • 83. How to choose Flowable and Observable When to source generate emission in regulated manner, especially true when the source in asynchronous and push larger amount of data. Network and Streaming APIs that can request a certain amount of returned results can easily be back pressured as well. Note: All the observable factories and operators are also applies in flowable.
  • 84. Converting Observable to Flowable Example public static void main(String[] args) throws InterruptedException { Observable<Integer> observable = Observable.range(1, 100000); observable.toFlowable(BackpressureStrategy.BUFFER).map(TestClass::new).observeOn(Schedulers.io()) .subscribe( s -> { sleep(50); System.out.println("Received: " + s.id); }); sleep(8000); } static final class TestClass { private final int id; TestClass(int id) { this.id = id; System.out.println("Constructing new Object: " + id); } }
  • 85. Converting Flowable to Observable Example public static void main(String[] args) throws InterruptedException { Flowable<Integer> flowable = Flowable.range(1, 10000).observeOn(Schedulers.io()); flowable.toObservable().map(TestClass::new).subscribe(item -> { sleep(50); System.out.println("Received: " + item.id); }); sleep(Long.MAX_VALUE); } static final class TestClass { private final int id; TestClass(int id) { this.id = id;
  • 86. MissingBackpressureException concept ● If we slowed down Flowable.interval(), our emissions would no longer reflect time intervals and become misleading. public static void main(String[] args) throws InterruptedException { Flowable.interval(1, TimeUnit.MILLISECONDS) .observeOn(Schedulers.io()) .map(wait -> sleep(wait)) .subscribe(System.out::println, Throwable::printStackTrace); sleep(Long.MAX_VALUE); } private static <R> R sleep(R wait) throws InterruptedException { Thread.sleep((Long) wait); return wait; }
  • 87. Let’s checkout some Backpressure Operators ● onBackPressureBuffer ● onBackPressureLatest ● onBackPressureDrop I think slide is going to be more than 100, so that’s why i am only demonstrating example Let’s understand all backpressure by looking in example:
  • 88. onBackPressureBuffer() public static void main(String[] args) throws InterruptedException { Flowable.interval(1, TimeUnit.MILLISECONDS) .onBackpressureBuffer(10, () -> System.out.println("DROP!!!!! OverFlow"), BackpressureOverflowStrategy.DROP_LATEST) .observeOn(Schedulers.io()) .subscribe(item -> { sleep(5); System.out.println(item); }); sleep(Long.MAX_VALUE); }
  • 89. onBackPressureLatest() public static void main(String[] args) throws InterruptedException { Flowable.interval(1, TimeUnit.MILLISECONDS) .onBackpressureLatest() .observeOn(Schedulers.io()) .subscribe( i -> { sleep(5); System.out.println(i); }); sleep(Long.MAX_VALUE); }
  • 90. onBackPressureDrop() public static void main(String[] args) throws InterruptedException { Flowable.interval(1, TimeUnit.MILLISECONDS) .onBackpressureDrop(i -> System.out.println("Dropping " + i)) .observeOn(Schedulers.io()) .subscribe(i -> { sleep(5); System.out.println(i); }); sleep(5000); }
  • 91. Multithreading With these three API you can bring multithreading in your project, no synchronization, wait, notify, notifyall etc.. It is easiest way to bring multithreading in our applications.. ● subscribeOn: Mechanism to add thread to our observable and subscribers. ● observeOn: It specifies on which scheduler the scubscriber should be notified. ● Schedulers: RxJava implements its own concurrency abstraction called Scheduler. schedulers.io() : This scheduler is meant for I/O operations.like: db schedulers.computation(): Default schedulers example: interval(), delay(), skip(), buffer() and user work etc.. schedulers.newThread(): It start new thread for the specified work. Schedulers.form(Custom Thread Management -Executor Java): Custom schedulers.immediate() and schedulers.trampoline() Note: I am going to discuss more example on multithreading.
  • 92. Let’s Look Simple Example Taking two thread and running the task parallely. Observable<String> green= Observable.just("A","B","C"); Observable<Integer> red= Observable.just(1,2,3); green.subscribeOn(Schedulers.computation()) .map(s->sleepOneSec(s)) .subscribe(System.out::println); red.subscribeOn(Schedulers.computation()) .map(s->sleepOneSec(s)) .subscribe(System.out::println); Thread.sleep(20000); //just for blocking main thread. private static <R> R sleepOneSec(R s) { Thread.sleep(2000); return s; } Output: A 1 B 2 C 3 Note:It can be in any order
  • 93. Zip in multithreading Observable<String> green = Observable.just("A", "B", "C") .subscribeOn(Schedulers.computation()) .map(s -> sleepOneSec(s)); Observable<Integer> red = Observable.just(1, 2, 3) .subscribeOn(Schedulers.computation()) .map(s -> sleepOneSec(s)); Observable.zip(green,red,(g,r)->g+" -- "+r).subscribe(System.out::println); Thread.sleep(8000); //to blocking main thread private static <R> R sleepOneSec(R s) throws InterruptedException { Thread.sleep(300); return s; Output: A -- 1 B -- 2 C -- 3
  • 94. Understanding subscribeOn() Observable.just(1,2,3,4) .subscribeOn(Schedulers.computation()) .map(s->s.hashCode()) .subscribe(s->System.out.println(Thread.currentThread().getName()+" - "+ s)); Observable.just(9,8,7,6) .subscribeOn(Schedulers.computation()) .map(s->s.hashCode()) .subscribe(s->System.out.println(Thread.currentThread().getName()+" - "+ s)); Thread.sleep(2000); Output: RxComputationThreadPool-2 - 9 RxComputationThreadPool-1 - 2 RxComputationThreadPool-2 - 8 RxComputationThreadPool-1 - 3 RxComputationThreadPool-2 - 7 RxComputationThreadPool-2 - 6 RxComputationThreadPool-1 - 4
  • 95. Each Observer getting its own thread Observable<String> observable = Observable.just("hey", "man", "rxjava") .subscribeOn(Schedulers.computation()); observable .map(s -> s.toUpperCase()) .subscribe(s -> System.out.println(Thread.currentThread().getName() + "- " + s)); observable .map(String::length) .subscribe(s -> System.out.println(Thread.currentThread().getName() + "- " + s)); Thread.sleep(20000); Output: RxComputationThreadPool-1- HEY RxComputationThreadPool-1- MAN RxComputationThreadPool-2- 3 RxComputationThreadPool-2- 3 RxComputationThreadPool-2- 6 RxComputationThreadPool-1- RXJAVA
  • 96. One Thread to Serve multiple Observer Observable<String> observable = Observable.just("hey", "man", "rxjava") .subscribeOn(Schedulers.computation()) .publish() .autoConnect(2); Observable .map(s->s.toUpperCase()) .subscribe(s->System.out.println(Thread.currentThread().getName()+"- "+s)); observable .map(String::length) .subscribe(s->System.out.println(Thread.currentThread().getName()+"- "+s)); Thread.sleep(5000); Output: RxComputationThreadPool-1- HEY RxComputationThreadPool-1- 3 RxComputationThreadPool-1- MAN RxComputationThreadPool-1- 3 RxComputationThreadPool-1- RXJAVA RxComputationThreadPool-1- 6
  • 97. How to make non-blocking call to API public static void main(String[] args) throws InterruptedException { Observable observable = Observable.fromCallable( () ->getResponse( "http://samples.openweathermap.org/data/2.5/forecast?id=524901&appid=b1b15e88fa797225412429c1c50c122a1")) .subscribeOn(Schedulers.io()); observable.subscribe(s -> System.out.println(Thread.currentThread().getName() + " = " + s)); doSomeThing(); doOtherTask(); } private static void doOtherTask() { System.out.println("Doing other task"); } private static void doSomeThing() throws InterruptedException { System.out.println("Excuting : " + Thread.currentThread().getName()); Thread.sleep(5000); } private static String getResponse(String path) { try { return new Scanner(new URL(path).openStream(), "UTF-8").useDelimiter("A").next(); } catch (Exception e) { return e.getMessage(); } }
  • 98. Understanding observeOn() Observable.just("WHISKEY/27653/TANGO", "6555/BRAVO", "232352/5675675/FOXTROT") .subscribeOn(Schedulers.io()) .flatMap(s -> Observable.fromArray(s.split("/"))) .doOnNext(s ->System.out.println( "Split out " + s + " on thread " + Thread.currentThread().getName())) .observeOn(Schedulers.computation()) .filter(s -> s.matches("[0-9]+")) .map(Integer::valueOf) .reduce((total, next) -> total + next) .doOnSuccess( s ->System.out.println("Calculated sum " + s + " on thread " + Thread.currentThread().getName())) .observeOn(Schedulers.io()) .map(i -> i.toString()) .doOnSuccess(s ->System.out.println( "Printing " + s + " on thread " + Thread.currentThread().getName())) .subscribe(s -> System.out.println(s)); We have changed io() thread to --->>> computation() and then to ---->>> io()
  • 99. How ExecutorService can be used in RxJava int numberOfThreadInPool=50; ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreadInPool); Scheduler schedulers = Schedulers.from(executorService); Observable.just(1,2,3,4,5,6,7,8) .subscribeOn(schedulers) .doFinally(executorService::shutdown) .subscribe(System.out::println); Output: 1 2 3 …..
  • 100. Reference ● http://www.reactivex.io ● https://github.com/ReactiveX/RxJava ● http://rxmarbles.com/ ● BackPressure: https://github.com/ReactiveX/RxJava/wiki/Backpressure ● https://medium.com/netflix-techblog/reactive-programming-in-the-netflix-api-with-rxjava- 7811c3a1496a ● http://www.baeldung.com/tag/rxjava/ There are many source but I prefer to read book by “Tomasz Nurkiewicz, Ben Christensen”
  • 101. Thanks! Enjoy writing code in reactive! Too much slide,ohh!... Even after cutting to many things. That’s why I am planning to record 3 to 4 hours video on RxJava.