├── .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 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 beerStock = new BeerStock(); 19 | 20 | 21 | static List 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 | --------------------------------------------------------------------------------