├── .gitignore
├── README.md
├── build.gradle
├── reactive_thinking.iml
├── slides
├── RXJava_Lviv.pdf
└── RXJava_Princeton_JUG.pdf
└── src
└── main
└── java
└── yfain
└── presentation
└── rxjava
├── BeerClient.java
├── BeerClientWithFailover.java
├── BeerServer.java
├── BeerServerWithFailover.java
├── HelloObservable.java
├── ObservableErrorComplete.java
├── StreamVsObservable.java
├── composingObservables
└── ObservableDrinks.java
├── drink
├── Beer.java
├── Drink.java
└── SoftDrink.java
├── schedulers
├── ParallelStreams.java
└── SubscribeOnObserveOn.java
└── stock
├── BeerStock.java
└── SoftDrinkStock.java
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | .idea
3 | .gradle
4 | build
5 | gradle
6 | gradlew
7 | gradlew.bat
8 | *.iml
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rxjava
2 | Code samples for the RxJava presentations
3 |
4 | My RxJava2 repo is here: https://github.com/yfain/rxjava2
5 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'java'
2 |
3 | sourceCompatibility = '1.8'
4 |
5 | repositories {
6 | jcenter()
7 | }
8 |
9 | dependencies {
10 | // https://mvnrepository.com/artifact/io.reactivex/rxjava
11 | compile group: 'io.reactivex', name: 'rxjava', version: '1.2.6'
12 |
13 | }
14 |
15 | task wrapper(type: Wrapper){
16 | gradleVersion = '3.4'
17 | }
--------------------------------------------------------------------------------
/reactive_thinking.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/slides/RXJava_Lviv.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfain/rxjava/8c5dafcaae1d26c4949b7343d2ba8780d172a555/slides/RXJava_Lviv.pdf
--------------------------------------------------------------------------------
/slides/RXJava_Princeton_JUG.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yfain/rxjava/8c5dafcaae1d26c4949b7343d2ba8780d172a555/slides/RXJava_Princeton_JUG.pdf
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/BeerClient.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava;
2 |
3 | import rx.Observable;
4 | import rx.Subscriber;
5 | import yfain.presentation.rxjava.drink.Beer;
6 |
7 | public class BeerClient {
8 | public static void main(String[] args) {
9 |
10 | Observable beerData = BeerServer.getData(); // no data coming in yet!!!
11 |
12 | beerData
13 | .subscribe(new Subscriber() {
14 |
15 | // Implementing the Observer
16 | public void onNext(Beer beer) {
17 | System.out.println(beer);
18 | }
19 |
20 | public void onError(Throwable throwable) {
21 | System.err.println("Client received: " + throwable.getMessage());
22 | }
23 |
24 | public void onCompleted() {
25 | System.out.println("*** The stream is over ***");
26 | }
27 | });
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/BeerClientWithFailover.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava; /**
2 | * Created by yfain11 on 4/19/16.
3 | */
4 | import rx.Observable;
5 | import yfain.presentation.rxjava.drink.Beer;
6 |
7 | public class BeerClientWithFailover {
8 | public static void main(String[] args) {
9 |
10 | Observable beerData = BeerServerWithFailover.getData(); // get data from main server
11 |
12 | beerData
13 | .onErrorResumeNext(err -> {
14 | System.out.println("!!! Switching to an alternative data source because of : "+ err.getMessage());
15 | return BeerServerWithFailover.getDataFromAnotherServer();}) // get data from alternative server
16 | .subscribe(
17 | // Implementing the observer
18 | beer -> System.out.println(beer),
19 | (error) -> System.err.println("Client received: " + error.getMessage()),
20 | () -> System.out.println("*** The stream is over ***")
21 | );
22 | }
23 | }
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/BeerServer.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava;
2 |
3 | import rx.Observable;
4 | import rx.Subscriber;
5 | import yfain.presentation.rxjava.drink.Beer;
6 | import yfain.presentation.rxjava.stock.BeerStock;
7 |
8 | public class BeerServer {
9 |
10 | private static BeerStock beerStock = new BeerStock();
11 |
12 |
13 | public static Observable getData(){
14 |
15 | System.out.println("*** Getting beers from the main data source ***");
16 |
17 | // Create an observable passing subscriber (implements Observer)
18 | // provided by the client
19 |
20 | Observable.OnSubscribe onSubscribe = subscriber -> {
21 | beerStock.forEach(beer -> BeerServer.subscribeBeer(subscriber, beer));
22 | subscriber.onCompleted();
23 | };
24 |
25 | return Observable.create(onSubscribe);
26 | }
27 |
28 | static void subscribeBeer(Subscriber super Beer> subscriber, Beer beer) {
29 | subscriber.onNext(beer);
30 |
31 | try {
32 | Thread.sleep(500); // Emulating delay in getting data
33 | } catch (InterruptedException e) {
34 | subscriber.onError(new Throwable("Error in getting beer info"));
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/BeerServerWithFailover.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava; /**
2 | * Created by yfain11 on 4/19/16.
3 | */
4 | import rx.Observable;
5 | import yfain.presentation.rxjava.drink.Beer;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | public class BeerServerWithFailover {
11 |
12 | public static Observable getData(){
13 |
14 | loadSeller();
15 | System.out.println("*** Getting beers from the main data source ***");
16 |
17 | // Create an observable passing subscriber (implements Observer)
18 | // provided by the client
19 | return
20 | Observable.create(subscriber -> {
21 | try {
22 | for (int i = 0; i < beerStock.size(); i++) {
23 |
24 | subscriber.onNext(beerStock.get(i));
25 |
26 | Thread.sleep(500); // Emulating delay in getting data
27 |
28 | if (Math.random() <0.3){ // Emulating data error
29 | throw new Throwable("Some stupid error");
30 | }
31 | }
32 | } catch(Throwable err){
33 | //err.printStackTrace();
34 | subscriber.onError(new Throwable("Error in getting beer info"));
35 | }
36 |
37 | subscriber.onCompleted();
38 | });
39 | }
40 |
41 | static List beerStock = new ArrayList<>();
42 |
43 | private static void loadSeller(){
44 | beerStock.add(new Beer("Obolon", "Ukraine", 4.00f));
45 | beerStock.add(new Beer("Stella", "Belgium", 7.75f));
46 | beerStock.add(new Beer("Sam Adams", "USA", 7.00f));
47 | beerStock.add(new Beer("Bud Light", "USA", 5.00f));
48 | beerStock.add(new Beer("Yuengling", "USA", 5.50f));
49 | beerStock.add(new Beer("Leffe Blonde", "Belgium", 8.75f));
50 | beerStock.add(new Beer("Chimay Blue", "Belgium", 10.00f));
51 | beerStock.add(new Beer("Brooklyn Lager", "USA", 8.25f));
52 |
53 | }
54 |
55 |
56 | public static Observable getDataFromAnotherServer(){
57 |
58 | System.out.println("*** Getting beers from the ALTERNATIVE data source ***");
59 |
60 | return
61 | Observable.create(subscriber -> {
62 | try {
63 | for (int i = 0; i < beerStock.size(); i++) {
64 |
65 | subscriber.onNext(beerStock.get(i));
66 |
67 | Thread.sleep(1000); // Emulating delay in getting data
68 |
69 | }
70 | } catch(Throwable err){
71 | subscriber.onError(new Throwable("Error in getting beer info"));
72 | }
73 |
74 | subscriber.onCompleted();
75 | });
76 | }
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/HelloObservable.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava; /**
2 | * Created by yfain11 on 4/9/16.
3 | */
4 | import rx.Observable;
5 | import yfain.presentation.rxjava.drink.Beer;
6 | import yfain.presentation.rxjava.stock.BeerStock;
7 |
8 | public class HelloObservable {
9 |
10 | private static BeerStock beerStock = new BeerStock();
11 |
12 | public static void main(String[] args) {
13 |
14 |
15 | Observable observableBeer = Observable.from(beerStock); // Create Observable from List
16 |
17 | observableBeer.subscribe(System.out::println); // onNext handler
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/ObservableErrorComplete.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava; /**
2 | * Created by yfain11 on 4/9/16.
3 | */
4 |
5 | import rx.Observable;
6 | import yfain.presentation.rxjava.drink.Beer;
7 | import yfain.presentation.rxjava.stock.BeerStock;
8 |
9 | public class ObservableErrorComplete {
10 |
11 | private static BeerStock beerStock = new BeerStock();
12 |
13 | public static void main(String[] args) {
14 |
15 | System.out.println("== Observable creation from an Iterable");
16 |
17 | Observable observableBeer = Observable.from(beerStock);
18 |
19 | observableBeer.subscribe(
20 | beer -> System.out.println(beer),
21 | error -> System.err.println(error),
22 | () -> System.out.println("Streaming is over")
23 | );
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/StreamVsObservable.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava; /**
2 | * Created by yfain11 on 4/9/16.
3 | */
4 | import rx.Observable;
5 | import yfain.presentation.rxjava.drink.Beer;
6 | import yfain.presentation.rxjava.stock.BeerStock;
7 |
8 | public class StreamVsObservable {
9 |
10 | private static BeerStock beerStock = new BeerStock();
11 |
12 | public static void main(String[] args) {
13 |
14 | // === Java 8 Stream
15 | System.out.println("\n== Iterating over Java 8 Stream");
16 |
17 | beerStock.stream()
18 | .skip(1)
19 | .limit(3)
20 | .filter(StreamVsObservable::isMadeInUSA)
21 | .map(StreamVsObservable::mapWithPrice)
22 | .forEach(System.out::println);
23 |
24 | // === RxJava Observable
25 |
26 | Observable observableBeer = null;
27 |
28 | System.out.println("\n== Subscribing to Observable ");
29 |
30 | observableBeer = Observable.from(beerStock);
31 |
32 | observableBeer
33 | .skip(1)
34 | .take(3)
35 | .filter(StreamVsObservable::isMadeInUSA)
36 | .map(StreamVsObservable::mapWithPrice)
37 | .subscribe(
38 | beer -> System.out.println(beer),
39 | err -> System.out.println(err),
40 | () -> System.out.println("Streaming is complete")
41 | );
42 | }
43 |
44 | static boolean isMadeInUSA(Beer beer){
45 | return "USA".equals(beer.country);
46 | }
47 |
48 | static String mapWithPrice(Beer beer) {
49 | return beer.name + ": $" + beer.price;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/composingObservables/ObservableDrinks.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava.composingObservables;
2 |
3 | import rx.Observable;
4 | import yfain.presentation.rxjava.drink.Beer;
5 | import yfain.presentation.rxjava.drink.Drink;
6 | import yfain.presentation.rxjava.drink.SoftDrink;
7 | import yfain.presentation.rxjava.stock.BeerStock;
8 | import yfain.presentation.rxjava.stock.SoftDrinkStock;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | public class ObservableDrinks {
14 |
15 | static List> drinks = new ArrayList<>();
16 |
17 |
18 | static List extends Drink> beerStock = new BeerStock();
19 |
20 |
21 | static List extends Drink> softStock = new SoftDrinkStock();
22 |
23 |
24 | public static Observable> getDrinks(){
25 |
26 | Observable> beerPallets = Observable.create(subscriber -> {
27 |
28 | subscriber.onNext(beerStock); // push the beers pallet
29 |
30 | subscriber.onNext(softStock); // push the soft drink pallet
31 |
32 | subscriber.onCompleted();
33 | });
34 |
35 | return beerPallets;
36 | }
37 |
38 | public static void main(String[] args) {
39 | Observable> pallets = getDrinks();
40 |
41 | pallets
42 | .flatMap(pallet -> Observable.from(pallet))
43 | .subscribe(
44 | data -> System.out.println("Subscriber received " + data),
45 | (error) -> System.err.println(error),
46 | () -> System.out.println("*** The stream is over ***")
47 | );
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/drink/Beer.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava.drink;
2 |
3 | public class Beer extends Drink {
4 | public Beer(String name, String country,float price){
5 | super(name, country, price);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/drink/Drink.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava.drink;
2 |
3 | public abstract class Drink {
4 | public String name;
5 | public String country;
6 | public float price;
7 |
8 | Drink(String name, String country,float price){
9 | this.name=name;
10 | this.country=country;
11 | this.price=price;
12 | }
13 |
14 | public String toString(){
15 | return name + "(" + country + ")";
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/drink/SoftDrink.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava.drink;
2 |
3 | public class SoftDrink extends Drink{
4 | public SoftDrink(String name, String country,float price){
5 | super(name, country, price);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/schedulers/ParallelStreams.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava.schedulers;
2 |
3 | import rx.schedulers.Schedulers;
4 | import rx.Observable;
5 | import yfain.presentation.rxjava.drink.Beer;
6 | import yfain.presentation.rxjava.stock.BeerStock;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | public class ParallelStreams {
12 | public static void main(String[] args) {
13 |
14 | List beers = new BeerStock(); // populate the beer collection
15 |
16 | Observable observableBeers = Observable.from(beers);
17 |
18 | observableBeers
19 | .flatMap(beer -> Observable.just(beer)
20 | .subscribeOn(Schedulers.computation()) // new thread for each observable
21 | .map(ParallelStreams::matureBeer)
22 | )
23 |
24 | .subscribe(ParallelStreams::log);
25 |
26 |
27 | // Just to keep the program running
28 | try {
29 | Thread.sleep(5000);
30 |
31 | } catch (InterruptedException e) {
32 | e.printStackTrace();
33 | }
34 | }
35 |
36 | private static void log(Beer beer) {
37 | System.out.println("Subscriber got " +
38 | beer.name + " on " +
39 | Thread.currentThread().getName());
40 | }
41 |
42 | private static Beer matureBeer(Beer beer){
43 | try {
44 | System.out.println("** Maturing " + beer.name +
45 | " on " + Thread.currentThread().getName());
46 |
47 | Thread.sleep((int)(Math.random()*500));
48 | return beer;
49 |
50 | } catch (InterruptedException e) {
51 | throw new RuntimeException(e);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/schedulers/SubscribeOnObserveOn.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava.schedulers;
2 |
3 | import rx.Observable;
4 | import rx.schedulers.Schedulers;
5 | import yfain.presentation.rxjava.drink.Beer;
6 | import yfain.presentation.rxjava.stock.BeerStock;
7 |
8 | import java.util.List;
9 |
10 | public class SubscribeOnObserveOn {
11 |
12 | public static void main(String[] args) {
13 |
14 | List beers = new BeerStock();// populate the beer collection
15 |
16 | Observable observableBeers = null;
17 |
18 | observableBeers.from(beers)
19 | .subscribeOn(Schedulers.computation()) // push data on computation thread
20 | .doOnNext(SubscribeOnObserveOn::log) // Side effect: Log on computation thread
21 | .observeOn(Schedulers.io()) // Process on another io thread
22 | .subscribe(SubscribeOnObserveOn::matureBeer);
23 |
24 | // Sleep just to keep the program running
25 | try {
26 | Thread.sleep(5000);
27 |
28 | } catch (InterruptedException e) {
29 | e.printStackTrace();
30 | }
31 |
32 | }
33 |
34 | private static void matureBeer(Beer beer){
35 | try {
36 | System.out.println("** Maturing " + beer.name +
37 | " on " + Thread.currentThread().getName());
38 |
39 | Thread.sleep((int)(Math.random()*500));
40 |
41 | } catch (InterruptedException e) {
42 | e.printStackTrace();
43 | }
44 |
45 | }
46 |
47 | private static void log(Beer beer){
48 | System.out.println("===> Logging " + beer.name +
49 | " on " + Thread.currentThread().getName() );
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/stock/BeerStock.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava.stock;
2 |
3 | import yfain.presentation.rxjava.drink.Beer;
4 |
5 | import java.util.ArrayList;
6 |
7 | /**
8 | * Created by ievgenii on 22.02.17.
9 | */
10 | public class BeerStock extends ArrayList {
11 | {
12 | add(new Beer("Obolon", "Ukraine", 4.00f));
13 | add(new Beer("Stella", "Belgium", 7.75f));
14 | add(new Beer("Sam Adams", "USA", 7.00f));
15 | add(new Beer("Bud Light", "USA", 5.00f));
16 | add(new Beer("Yuengling", "USA", 5.50f));
17 | add(new Beer("Leffe Blonde", "Belgium", 8.75f));
18 | add(new Beer("Chimay Blue", "Belgium", 10.00f));
19 | add(new Beer("Brooklyn Lager", "USA", 8.25f));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/yfain/presentation/rxjava/stock/SoftDrinkStock.java:
--------------------------------------------------------------------------------
1 | package yfain.presentation.rxjava.stock;
2 |
3 | import yfain.presentation.rxjava.drink.Drink;
4 | import yfain.presentation.rxjava.drink.SoftDrink;
5 |
6 | import java.util.ArrayList;
7 |
8 | /**
9 | * Created by ievgenii on 22.02.17.
10 | */
11 | public class SoftDrinkStock extends ArrayList {
12 | {
13 | add(new SoftDrink("Lemonade", "Ukraine", 1.00f));
14 | add(new SoftDrink("Pepsi", "USA", 2.00f));
15 | add(new SoftDrink("Fanta", "USA", 3.00f));
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------