package com.github.jhusain.learnrxjava.grokking; import rx.Observable; import rx.Observable.OnSubscribe; import rx.Subscriber; import rx.functions.Action1; import rx.functions.Func1; import rx.schedulers.Schedulers; /** * Created by zqhxuyuan on 15-4-2. * * Ref: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/ */ public class HelloWorld { public static void main(String[] args) { //helloword(); //simpleCode(); oneShort(); } public static void helloword(){ /** * When the subscription is made, * myObservable calls the subscriber's onNext() and onComplete() methods. * As a result, mySubscriber outputs "Hello, world!" then terminates. */ //create a basic Observable Observable<String> myObservable = Observable.create( new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> sub) { sub.onNext("Hello, world!"); sub.onCompleted(); } } ); //create a Subscriber to consume the data Subscriber<String> mySubscriber = new Subscriber<String>() { @Override public void onNext(String s) { System.out.println(s); } @Override public void onCompleted() { System.out.println("complete!"); } @Override public void onError(Throwable e) { } }; //hook them up to each other using subscribe() myObservable.subscribe(mySubscriber); } public static void simpleCode(){ //emits a single item then completes Observable<String> myObservable = Observable.just("Hello, world!"); //don't care about onCompleted() nor onError(), so instead we can //use a simpler class to define what to do during onNext() Action1<String> onNextAction = new Action1<String>() { @Override public void call(String s) { System.out.println(s); } }; //Actions can define each part of a Subscriber //we only need the first parameter, because we're ignoring onError() and onComplete() myObservable.subscribe(onNextAction); } public static void oneShort(){ Observable.just("Hello, world!") .subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println(s); } }); } public static void java8Style(){ Observable.just("Hello, world!") .subscribe(s -> System.out.println(s)); } public static void firstTransformation(){ //control over your Observable Observable.just("Hello, world! -Dan") .subscribe(s -> System.out.println(s)); //modifying our Subscriber instead Observable.just("Hello, world!") .subscribe(s -> System.out.println(s + " -Dan")); //Subscribers are supposed to be the thing that reacts, not the thing that mutates } //Operators can be used in between the source Observable and //the ultimate Subscriber to manipulate emitted items public static void introduceOperators(){ //the map() operator can be used to transform one emitted item into another Observable.just("Hello, world!") .map(new Func1<String, String>() { @Override public String call(String s) { return s + " -Dan"; } }) .subscribe(s -> System.out.println(s)); //lambdas Observable.just("Hello, world!") .map(s -> s + " -Dan") .subscribe(s -> System.out.println(s)); //Our map() operator is basically an Observable that transforms an item. //We can chain as many map() calls as we want together, //polishing the data into a perfect, consumable form for our end Subscriber } public static void moreMapOperators(){ //we started with a String but our Subscriber receives an Integer Observable.just("Hello, world!") .map(new Func1<String, Integer>() { @Override public Integer call(String s) { return s.hashCode(); } }) .subscribe(i -> System.out.println(Integer.toString(i))); Observable.just("Hello, world!") .map(s -> s.hashCode()) .subscribe(i -> System.out.println(Integer.toString(i))); //we want our Subscriber to do as little as possible Observable.just("Hello, world!") .map(s -> s.hashCode()) .map(i -> Integer.toString(i)) .subscribe(s -> System.out.println(s)); //We just added some transformational steps in between Observable.just("Hello, world!") .map(s -> s + " -Dan") .map(s -> s.hashCode()) .map(i -> Integer.toString(i)) .subscribe(s -> System.out.println(s)); } }