├── .gitignore ├── README.md ├── Reactive.pptx ├── license ├── pom.xml └── src └── main └── java └── com └── vgrazi ├── observable ├── EmitterLauncher.java ├── Launcher.java ├── MetronomeLauncher.java └── WordLauncher.java ├── play ├── BufferThrottleExample.java ├── ConnectedPublisherExamples.java ├── Examples.java ├── GeneralCodeSamples.java ├── MapFlatMapExamples.java ├── MathExamples.java ├── PriceTick.java ├── SomeFeed.java ├── SomeListener.java └── reactive.java └── util └── Utils.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Maven template 3 | target/ 4 | pom.xml.tag 5 | pom.xml.releaseBackup 6 | pom.xml.versionsBackup 7 | pom.xml.next 8 | release.properties 9 | dependency-reduced-pom.xml 10 | buildNumber.properties 11 | .mvn/timing.properties 12 | 13 | .gitignore 14 | .idea/ 15 | reactive.iml 16 | Reactive play/reactive (1).iml 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rxjava-snippets 2 | Reactive rx-java code snippets 3 | 4 | There are three launchers representing the examples in our article. Just do a maven install of the project and launch the main of each: 5 | 6 | 1. WordLauncher - The "quick brown fox" example 7 | 2. MetronomeLauncher - Merging the two streams to produce a clock that varies every 15 seconds 8 | 3. EmitterLauncher - Emits stock feeds. These are randomly generated, don't go out and buy or sell based on this!! 9 | 10 | The other examples in the various testers are random reactive examples 11 | -------------------------------------------------------------------------------- /Reactive.pptx: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Victor J Grazi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.vgrazi.play 8 | reactive 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 16 | 1.8 17 | 1.8 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | io.reactivex 26 | rxjava 27 | 1.1.10 28 | 29 | 30 | io.reactivex 31 | rxjava-math 32 | RELEASE 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | junit 41 | junit 42 | RELEASE 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/observable/EmitterLauncher.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.observable; 2 | 3 | import com.vgrazi.play.PriceTick; 4 | import com.vgrazi.play.SomeFeed; 5 | import com.vgrazi.play.SomeListener; 6 | import rx.AsyncEmitter; 7 | import rx.Observable; 8 | import rx.observables.ConnectableObservable; 9 | 10 | import static com.vgrazi.util.Utils.sleep; 11 | 12 | public class EmitterLauncher { 13 | public static void main(String[] args) { 14 | SomeFeed feed = new SomeFeed<>(); 15 | Observable obs = 16 | Observable.fromEmitter((AsyncEmitter emitter) -> 17 | { 18 | SomeListener listener = new SomeListener() { 19 | @Override 20 | public void priceTick(PriceTick event) { 21 | emitter.onNext(event); 22 | if (event.isLast()) { 23 | emitter.onCompleted(); 24 | } 25 | } 26 | 27 | @Override 28 | public void error(Throwable e) { 29 | emitter.onError(e); 30 | } 31 | }; 32 | feed.register(listener); 33 | }, AsyncEmitter.BackpressureMode.BUFFER); 34 | 35 | ConnectableObservable hotObservable = obs.publish(); 36 | hotObservable.connect(); 37 | 38 | hotObservable.take(10).subscribe((priceTick) -> 39 | System.out.printf("1 %s %4s %6.2f%n", priceTick.getDate(), 40 | priceTick.getInstrument(), priceTick.getPrice())); 41 | 42 | sleep(1_000); 43 | 44 | hotObservable.take(10).subscribe((priceTick) -> 45 | System.out.printf("2 %s %4s %6.2f%n", priceTick.getDate(), 46 | priceTick.getInstrument(), priceTick.getPrice())); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/observable/Launcher.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.observable; 2 | 3 | import rx.Observable; 4 | 5 | import java.util.Date; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | import static com.vgrazi.util.Utils.isSlowTime; 9 | import static com.vgrazi.util.Utils.sleep; 10 | 11 | public class Launcher 12 | { 13 | 14 | public static void main(String[] args) 15 | { 16 | new Launcher().launch(); 17 | } 18 | 19 | private void launch() 20 | { 21 | Observable slow = Observable.interval(2, TimeUnit.SECONDS); 22 | Observable fast = Observable.interval(1, TimeUnit.SECONDS); 23 | Observable.merge( 24 | slow.filter(x->isSlowTime()), 25 | fast.filter(x->!isSlowTime()) 26 | ) 27 | .subscribe(x-> System.out.println(new Date())) 28 | ; 29 | 30 | sleep(50_000); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/observable/MetronomeLauncher.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.observable; 2 | 3 | import rx.Observable; 4 | 5 | import java.util.Date; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | import static com.vgrazi.util.Utils.isSlowTime; 9 | import static com.vgrazi.util.Utils.sleep; 10 | 11 | public class MetronomeLauncher 12 | { 13 | 14 | public static void main(String[] args) 15 | { 16 | new MetronomeLauncher().launch(); 17 | } 18 | 19 | private void launch() 20 | { 21 | Observable fast = Observable.interval(1, TimeUnit.SECONDS); 22 | Observable slow = Observable.interval(2, TimeUnit.SECONDS); 23 | final int[] i = {1}; 24 | Observable.merge( 25 | fast.filter(x -> !isSlowTime()), 26 | slow.filter(x -> isSlowTime()) 27 | ) 28 | .subscribe(x -> System.out.println(i[0]++ + " " + new Date())) 29 | ; 30 | sleep(50_000); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/observable/WordLauncher.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.observable; 2 | 3 | import rx.Observable; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | public class WordLauncher 9 | { 10 | 11 | public static void main(String[] args) 12 | { 13 | new WordLauncher().launch(); 14 | } 15 | 16 | private void launch() 17 | { 18 | List words = Arrays.asList( 19 | "the", 20 | "quick", 21 | "brown", 22 | "fox", 23 | "jumped", 24 | "over", 25 | "the", 26 | "lazy", 27 | "dogs" 28 | ); 29 | 30 | Observable.from(words) 31 | .flatMap(word -> Observable.from(word.split(""))) 32 | .distinct() 33 | .sorted() 34 | .zipWith(Observable.range(1, Integer.MAX_VALUE), 35 | (string, count)->String.format("%2d. %s", count, string)) 36 | .subscribe(System.out:: println); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/BufferThrottleExample.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | import org.junit.Test; 4 | import rx.Observable; 5 | import rx.Subscriber; 6 | import rx.Subscription; 7 | import rx.functions.Func0; 8 | import rx.functions.Func1; 9 | 10 | import javax.swing.*; 11 | import java.awt.*; 12 | import java.awt.event.MouseAdapter; 13 | import java.awt.event.MouseEvent; 14 | import java.awt.event.MouseMotionAdapter; 15 | import java.awt.event.MouseMotionListener; 16 | import java.util.Collections; 17 | import java.util.Date; 18 | import java.util.List; 19 | import java.util.concurrent.TimeUnit; 20 | 21 | /** 22 | * Created by victorg on 8/2/2016. 23 | */ 24 | public class BufferThrottleExample { 25 | private final JPanel panel = new JPanel(); 26 | @Test 27 | public void mouseClickTest() throws InterruptedException { 28 | JFrame frame = new JFrame(); 29 | frame.setBounds(100, 100, 500, 500); 30 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 31 | JLabel label = new JLabel("Test"); 32 | panel.add(label); 33 | panel.setBackground(Color.yellow); 34 | frame.getContentPane().add(panel); 35 | frame.setVisible(true); 36 | 37 | Observable mouseObservable = Observable.create(subscriber -> { 38 | panel.addMouseListener(new MouseAdapter() { 39 | @Override 40 | public void mouseClicked(MouseEvent e) { 41 | subscriber.onNext(String.format("Clicked at %d, %d", e.getX(), e.getY())); 42 | } 43 | }); 44 | }); 45 | 46 | Subscription subscription = mouseObservable 47 | .debounce(400, TimeUnit.MILLISECONDS) 48 | // .window(400, TimeUnit.MILLISECONDS) 49 | // .toList() 50 | .doOnNext((x) -> System.out.println(new Date() + x.toString())) 51 | // .filter(list -> !list.isEmpty()) 52 | // .map(list -> list.get(list.size() - 1)) 53 | .subscribe((text) -> label.setText(text.toString())); 54 | Thread.sleep(10_000); 55 | } 56 | 57 | @Test 58 | public void mouseMoveTest() throws InterruptedException { 59 | JFrame frame = new JFrame(); 60 | frame.setBounds(100, 100, 500, 500); 61 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 62 | JLabel label = new JLabel("Test"); 63 | panel.add(label); 64 | panel.setBackground(Color.yellow); 65 | frame.getContentPane().add(panel); 66 | frame.setVisible(true); 67 | 68 | Observable observable = Observable.create(subscriber -> { 69 | panel.addMouseMotionListener(new MouseMotionListener() { 70 | @Override 71 | public void mouseDragged(MouseEvent e) { 72 | subscriber.onNext(String.format("Dragged to %d, %d", e.getX(), e.getY())); 73 | } 74 | 75 | @Override 76 | public void mouseMoved(MouseEvent e) { 77 | subscriber.onNext(String.format("Moved to %d, %d", e.getX(), e.getY())); 78 | } 79 | }); 80 | }); 81 | 82 | observable.buffer(new Func0>() { 83 | @Override 84 | public Observable call() { 85 | return Observable.just(new Date() + " Hit"); 86 | } 87 | }) 88 | .doOnNext(System.out::println) 89 | .debounce(500, TimeUnit.MILLISECONDS) 90 | .subscribe(System.out::println); 91 | 92 | // observable.buffer(100, TimeUnit.MILLISECONDS) 93 | // .doOnNext(System.out::println) 94 | // .filter(list -> !list.isEmpty()) 95 | // .map(list -> list.get(list.size() - 1)) 96 | // .subscribe(label::setText); 97 | Thread.sleep(100_000); 98 | } 99 | @Test 100 | public void test() throws InterruptedException { 101 | Observable.interval(100, TimeUnit.MILLISECONDS) 102 | .buffer(Observable.interval(500, TimeUnit.MILLISECONDS)) 103 | .doOnNext(System.out::println) 104 | .map(Collections::max) 105 | .subscribe(System.out::println); 106 | 107 | Thread.sleep(100_000); 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/ConnectedPublisherExamples.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | import rx.Observable; 4 | import rx.Subscription; 5 | import rx.observables.ConnectableObservable; 6 | 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * Created by victorg on 7/28/2016. 11 | */ 12 | public class ConnectedPublisherExamples { 13 | 14 | public static void main(String[] args) throws Exception{ 15 | // Observable hotObservable = Observable.interval(1, TimeUnit.SECONDS); 16 | ConnectableObservable hotObservable = Observable.interval(1, TimeUnit.SECONDS).publish(); 17 | 18 | // hotObservable.refCount(); 19 | hotObservable.autoConnect(2); 20 | // hotObservable.autoConnect(2, s->System.out.println(s + " connected")); 21 | Subscription subscriber1 = hotObservable.subscribe(val -> System.out.println("Subscriber 1 >> " + val)); 22 | 23 | Thread.sleep(4000); 24 | 25 | Subscription subscriber2 = hotObservable.subscribe(val -> System.out.println("Subscriber 2 >> " + val)); 26 | // Thread.sleep(1000); 27 | // subscriber1.unsubscribe(); 28 | 29 | // Thread.sleep(1000); 30 | // subscriber2.unsubscribe(); 31 | // 32 | // hotObservable.connect(); 33 | 34 | Thread.sleep(50_000); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/Examples.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | import java.util.Date; 4 | 5 | public class Examples { 6 | public static void main(String[] args) { 7 | // SomeFeed feed = new SomeFeed<>(); 8 | // 9 | // Observable observable = 10 | // Observable.fromAsync((AsyncEmitter emitter) -> { 11 | // SomeListener listener = new SomeListener() { 12 | // @Override 13 | // public void priceTick(PriceTick event) { 14 | // emitter.onNext(event); 15 | // if (event.isLast()) { 16 | // emitter.onCompleted(); 17 | // } 18 | // } 19 | // 20 | // @Override 21 | // public void error(Throwable e) { 22 | // emitter.onError(e); 23 | // } 24 | // }; 25 | // 26 | // feed.register(listener); 27 | // }, AsyncEmitter.BackpressureMode.BUFFER); 28 | // 29 | // 30 | // observable.subscribe(x -> System.out.printf("%2d %s %4s %6.2f%n", x.getSequence(), x.getDate(), x.getInstrument(), x.getPrice()), System.out::println, () -> System.out.println("Complete")); 31 | // Observable range = Observable.range(1, Integer.MAX_VALUE); 32 | // Observable words = Observable.just( 33 | // "the", 34 | // "quick", 35 | // "brown", 36 | // "fox", 37 | // "jumped", 38 | // "over", 39 | // "the", 40 | // "lazy", 41 | // "dog" 42 | // ); 43 | // words. 44 | // flatMap(w -> Observable.from(w.split(""))) 45 | // .distinct() 46 | // .sorted() 47 | // .zipWith(Observable.range(1, Integer.MAX_VALUE), (letter, counter) -> String.format("%2d. %s", counter, letter)) 48 | // .subscribe(System.out::println); 49 | // 50 | // Observable weekday = Observable.interval(5, TimeUnit.SECONDS) 51 | // .filter(x -> isWeekend()); 52 | // 53 | // Observable weekend = Observable.interval(2, TimeUnit.SECONDS) 54 | // .filter(x -> !isWeekend()); 55 | // 56 | // Observable.merge(weekend, weekday) 57 | // .subscribe(x -> System.out.println(new Date())); 58 | // 59 | // sleep(100_000); 60 | } 61 | 62 | 63 | private static boolean isWeekend() { 64 | Date now = new Date(); 65 | return now.getSeconds() > 30; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/GeneralCodeSamples.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | import org.junit.Test; 4 | import rx.*; 5 | import rx.Observable; 6 | import rx.functions.Action0; 7 | import rx.functions.Action1; 8 | import rx.observables.ConnectableObservable; 9 | import rx.observables.MathObservable; 10 | import rx.schedulers.Schedulers; 11 | import rx.subjects.AsyncSubject; 12 | import rx.subjects.Subject; 13 | 14 | import java.io.IOException; 15 | import java.util.*; 16 | import java.util.concurrent.*; 17 | 18 | public class GeneralCodeSamples { 19 | 20 | @Test 21 | public void testCreate() { 22 | Observable.create(s -> s.onNext("Hello, world")) 23 | .subscribe(System.out::println); 24 | 25 | } 26 | 27 | @Test 28 | public void testCreateTwo() { 29 | Observable.create( 30 | subscriber -> { 31 | subscriber.onNext("Hello,"); 32 | subscriber.onNext("World"); 33 | } 34 | ) 35 | .subscribe(System.out::println); 36 | 37 | } 38 | 39 | @Test 40 | public void testCreateWithComplete() { 41 | Observable.create( 42 | subscriber -> { 43 | subscriber.onNext("Hello,"); 44 | subscriber.onNext("World"); 45 | subscriber.onCompleted(); 46 | } 47 | ) 48 | .subscribe(System.out::println, System.out::println, () -> System.out.println("Complete")); 49 | 50 | } 51 | 52 | @Test 53 | public void testCreateWithError() { 54 | Observable observable = Observable.create( 55 | subscriber -> { 56 | subscriber.onNext("Hello,"); 57 | subscriber.onNext("World"); 58 | subscriber.onError(new IOException("test exception")); 59 | subscriber.onNext("Ignored after error"); 60 | subscriber.onCompleted(); 61 | } 62 | ); 63 | 64 | observable.subscribe(System.out::println, System.out::println, () -> System.out.println("Complete")); 65 | } 66 | 67 | @Test 68 | public void testCreateWithErrorCorrection() { 69 | 70 | Observable observable = Observable.create( 71 | subscriber -> { 72 | subscriber.onNext("Hello,"); 73 | subscriber.onNext("World"); 74 | subscriber.onError(new IOException("test exception")); 75 | subscriber.onNext("Ignored after error"); 76 | // subscriber.onError(new IOException("test exception")); 77 | subscriber.onNext("Ignored after 2nd error"); 78 | subscriber.onCompleted(); 79 | } 80 | ); 81 | 82 | // Observable observable1 = observable 83 | // .onErrorReturn(o -> "ERROR CORRECTED") 84 | // .doOnError(System.out::println); 85 | 86 | ConcurrentLinkedDeque> sources = new ConcurrentLinkedDeque<>(); 87 | Observable observable1 = Observable.combineLatestDelayError(sources, args -> Arrays.asList(args).toString()); 88 | observable1.subscribe(System.out::println, 89 | System.out::println, () -> System.out.println("Complete")); 90 | System.out.println(sources); 91 | Scheduler scheduler = Schedulers.immediate(); 92 | // Scheduler scheduler = Schedulers.computation(); 93 | // Scheduler scheduler = Schedulers.from(Executor); 94 | // Scheduler scheduler = Schedulers.io(); 95 | // Scheduler scheduler = Schedulers.newThread(); 96 | // Scheduler scheduler = Schedulers.trampoline(); 97 | observable.subscribeOn(scheduler); 98 | } 99 | 100 | @Test 101 | public void testConvertObservableToInt() { 102 | Integer sum = MathObservable.sumInteger(Observable.just(1, 2, 8, 9, 10, 11)).toBlocking().first(); 103 | System.out.println(sum); 104 | 105 | List list = Observable.just("it", "was", "the", "best", "of", "times").buffer(100).toBlocking().single(); 106 | System.out.println(list); 107 | } 108 | 109 | @Test 110 | public void testRangeZip() { 111 | Observable counters = Observable 112 | .range(1, Integer.MAX_VALUE) 113 | // .doOnNext(x-> System.out.println("On Next:" + x)) 114 | ; 115 | List list = Arrays.asList( 116 | "the", 117 | "quick", 118 | "brown", 119 | "fox", 120 | "jumped", 121 | "over", 122 | "the", 123 | "lazy", 124 | "dog" 125 | ); 126 | Observable 127 | .from(list) 128 | .flatMap(x-> Observable.from(x.split(""))) 129 | .distinct() 130 | .sorted() 131 | .zipWith(counters, (x, y)->String.format("%2d. %s", y, x)) 132 | .subscribe(System.out::println); 133 | } 134 | 135 | 136 | @Test 137 | public void testFromAsync() { 138 | SomeFeed feed = new SomeFeed(); 139 | 140 | // Observable observable = Observable.fromAsync((AsyncEmitter emitter) -> { 141 | // SomeListener listener = new SomeListener() { 142 | // @Override 143 | // public void priceTick(PriceTick event) { 144 | //// emitter.onNext(throwException()); 145 | // emitter.onNext(event); 146 | // if (event.isLast()) { 147 | // emitter.onCompleted(); 148 | // } 149 | // } 150 | // 151 | // @Override 152 | // public void error(Throwable e) { 153 | // emitter.onError(e); 154 | // } 155 | // }; 156 | // 157 | // 158 | // feed.register(listener); 159 | // 160 | // }, AsyncEmitter.BackpressureMode.BUFFER).doOnNext((x) -> print("doOnNext:" + x)); 161 | //// ConnectableObservable connectableObservable = observable.publish(); 162 | //// connectableObservable.connect(); 163 | // sleep(3_000); 164 | // 165 | //// Subscription subscription = observable.subscribe(Logger::print); 166 | // Subscription subscription = observable.subscribe(Logger::print, Logger::print, ()-> System.out.println("Complete")); 167 | // sleep(3_000); 168 | // subscription.unsubscribe(); 169 | 170 | } 171 | 172 | 173 | @Test 174 | public void testAttachFeed() { 175 | SomeFeed feed = new SomeFeed(3); 176 | Observable.create(s -> 177 | feed.register(new SomeListener() { 178 | @Override 179 | public void priceTick(PriceTick event) { 180 | s.onNext(event); 181 | } 182 | 183 | @Override 184 | public void error(Throwable throwable) { 185 | s.onError(throwable); 186 | } 187 | }) 188 | ).subscribe(System.out::println); 189 | 190 | sleep(500_000); 191 | } 192 | 193 | // @Test 194 | // public void testAttachFeedWithMap() { 195 | // SomeFeed feed = new SomeFeed(3); 196 | // Observable.create(s -> 197 | // feed.register(new SomeListener() { 198 | // @Override 199 | // public void priceTick(String event) { 200 | // s.onNext(event); 201 | // } 202 | // 203 | // @Override 204 | // public void error(Throwable throwable) { 205 | // s.onError(throwable); 206 | // } 207 | // }) 208 | // ) 209 | // .subscribe(System.out::println); 210 | // 211 | // sleep(500_000); 212 | // } 213 | 214 | 215 | @Test 216 | public void just_1() { 217 | Observable.just("Hello, World") 218 | .subscribe(System.out::println); 219 | } 220 | 221 | @Test 222 | public void just_2() { 223 | Observable.just("Hello", "World") 224 | .subscribe(System.out::println); 225 | } 226 | 227 | @Test 228 | public void buffer() { 229 | Observable.just("Hello", "World") 230 | .buffer(2) 231 | .subscribe(System.out::println); 232 | } 233 | 234 | @Test 235 | public void bufferWithOverflow() { 236 | Observable.just("Hello", "World") 237 | .buffer(30) 238 | .subscribe(System.out::println); 239 | } 240 | 241 | @Test 242 | public void testJustWithNull() { 243 | Observable.just("Hello", "World", null) 244 | .buffer(30) 245 | .subscribe(System.out::println); 246 | } 247 | 248 | @Test 249 | public void testJustWithNullFiltered() { 250 | Observable.just("Hello", "World", null) 251 | .filter(s -> s != null) 252 | .buffer(30) 253 | .subscribe(System.out::println); 254 | } 255 | 256 | @Test 257 | public void testJustWithNullsFiltered() { 258 | List list = Arrays.asList("Hello", null, "World", null, null, "Goodbye", "Cruel", "World"); 259 | Observable.from(list) 260 | .filter(s -> s != null) 261 | .buffer(2) 262 | .subscribe(System.out::println); 263 | } 264 | 265 | @Test 266 | public void testMax() { 267 | Integer[] list = new Integer[]{10, 20, null, 30, 40, 50}; 268 | Observable observable = Observable.from(list); 269 | Observable buffer = MathObservable.from(observable) 270 | .max(Integer::compareTo); 271 | buffer.subscribe(System.out::println, 272 | Throwable::printStackTrace, 273 | () -> System.out.println("Complete")); 274 | } 275 | 276 | @Test 277 | public void testSum() { 278 | Integer[] list = new Integer[]{10, 20, null, 30, 40, 50}; 279 | Observable observable = Observable.from(list) 280 | .filter(s -> s != null); 281 | Observable buffer = MathObservable.from(observable) 282 | .sumInteger(s -> s * 10); 283 | 284 | buffer.subscribe(System.out::println, 285 | Throwable::printStackTrace, 286 | () -> System.out.println("Complete")); 287 | } 288 | 289 | @Test 290 | public void testMath() { 291 | Integer[] list = new Integer[]{10, 60, null, 65, 70, 80}; 292 | Observable observable = Observable.from(list) 293 | .filter(s -> s != null); 294 | 295 | Observable sum = MathObservable.from(observable) 296 | .sumDouble(s -> s * 1d); 297 | 298 | Observable max = MathObservable.from(observable) 299 | .max(Integer::compareTo) 300 | .map(s -> s * 1.); 301 | 302 | Observable min = MathObservable.from(observable) 303 | .min(Integer::compareTo) 304 | .map(s -> s * 1.); 305 | 306 | Observable medianStream = max.mergeWith(min); 307 | 308 | Observable midrange = MathObservable.from(medianStream).averageDouble(s -> s); 309 | midrange.subscribe((x) -> System.out.println("Mid range:" + x)); 310 | 311 | Observable midrangeInt = MathObservable.from(medianStream).averageInteger(Double::intValue); 312 | midrangeInt.subscribe((x) -> System.out.println("Mid range int:" + x)); 313 | 314 | sum.subscribe((x) -> System.out.println("Sum:" + x), 315 | Throwable::printStackTrace, 316 | () -> System.out.println("Complete")); 317 | } 318 | 319 | // @Test 320 | // public void testReduce() { 321 | // Integer[] list = new Integer[]{10, 60, null, 65, 70, 80}; 322 | // Observable observable = Observable.from(list) 323 | // .filter(s -> s != null); 324 | // 325 | // Observable sum = MathObservable.from(observable) 326 | // .sumDouble(s -> s * 1d); 327 | // ; 328 | // 329 | // Observable max = MathObservable.from(observable) 330 | // .max(Integer::compareTo) 331 | // .map(s -> s * 1.); 332 | // 333 | // Observable min = MathObservable.from(observable) 334 | // .min(Integer::compareTo) 335 | // .map(s -> s * 1.); 336 | // 337 | // Observable medianStream = max.mergeWith(min); 338 | // 339 | // Observable midrange = MathObservable.from(medianStream).averageDouble(s -> s); 340 | // midrange.subscribe((x) -> System.out.println("Mid range:" + x)); 341 | // 342 | // Observable midrangeInt = MathObservable.from(medianStream).averageInteger(Double::intValue); 343 | // midrangeInt.subscribe((x) -> System.out.println("Mid range int:" + x)); 344 | // 345 | // Observable range = MathObservable.from(medianStream).sumDouble( 346 | // new Func1() { 347 | // @Override 348 | // public Double call(Double aDouble) { 349 | // return null; 350 | // } 351 | // } 352 | // ); 353 | // range.reduce(0, (a, b) -> { 354 | // return abs(b - a); 355 | // }); 356 | // range.subscribe((x) -> System.out.println("Range int:" + x)); 357 | // 358 | // 359 | // sum.subscribe((x) -> System.out.println("Sum:" + x), 360 | // Throwable::printStackTrace, 361 | // () -> System.out.println("Complete")); 362 | // } 363 | 364 | @Test 365 | public void test_9() { 366 | Integer[] list = new Integer[]{10, 20, 30, 40, 50}; 367 | // List list = Arrays.asList(10, 20, 30, 40, 50); 368 | Observable> buffer = Observable.from(list) 369 | // Observable buffer = Observable.from(list) 370 | .filter(s -> s != null) 371 | .buffer(30); 372 | buffer.subscribe(System.out::println, 373 | System.out::println, 374 | () -> System.out.println("Complete")); 375 | } 376 | 377 | @Test 378 | public void testRange() { 379 | Observable observable = Observable.range(100, 10); 380 | 381 | observable.subscribe(System.out::println); 382 | } 383 | 384 | 385 | @Test 386 | public void projectEulerTest1() { 387 | // sum numbers from 1 to 1000 divisible by 3 and/or 5 388 | Observable valid = Observable.range(1, 999) 389 | .filter(s -> s % 3 == 0 || s % 5 == 0) 390 | .doOnNext(System.out::println) 391 | .reduce(0, (a, b) -> a + b); 392 | 393 | valid.subscribe(System.out::println); 394 | } 395 | 396 | @Test 397 | public void projectEulerTest2() { 398 | Observable threes = Observable.range(1, 999).map(i -> i * 3).takeWhile(i -> i < 1000); 399 | Observable fives = Observable.range(1, 999).map(i -> i * 5).takeWhile(i -> i < 1000); 400 | Observable threesAndFives = Observable 401 | .merge(threes, fives) 402 | .distinct(); 403 | 404 | threesAndFives.reduce(0, (a, b) -> a + b) 405 | .subscribe(System.out::println); 406 | } 407 | 408 | @Test 409 | public void testMidRange() { 410 | Integer[] list = {10, 80, 90, 100}; 411 | Observable ints = Observable.from(list); 412 | Observable min = MathObservable.from(ints).min(Integer::compareTo); 413 | Observable max = MathObservable.from(ints).max(Integer::compareTo); 414 | // min.zipWith(max, (a, b) -> (b + a) / 2).subscribe(System.out::println); 415 | Observable.zip(min, max, (a, b) -> (b + a) / 2).subscribe(System.out::println); 416 | } 417 | 418 | @Test 419 | public void testSubject() throws InterruptedException { 420 | ExecutorService executor = Executors.newCachedThreadPool(); 421 | Subject subject = AsyncSubject.create(); 422 | getThread(executor, subject); 423 | getThread(executor, subject); 424 | 425 | subject.subscribe( 426 | v -> System.out.println(v), // happy path 427 | System.out::println, // error handler 428 | () -> System.out.println("Complete")); // complete 429 | 430 | Thread.sleep(12_000); 431 | } 432 | 433 | private void getThread(ExecutorService executor, Subject subject) { 434 | executor.execute(() -> 435 | { 436 | for (int i = 0; i < 10; i++) { 437 | System.out.println("onNext " + i); 438 | subject.onNext(i); 439 | try { 440 | Thread.sleep(500); 441 | } catch (InterruptedException e) { 442 | subject.onError(e); 443 | } 444 | } 445 | System.out.println("completing"); 446 | subject.onCompleted(); 447 | }); 448 | } 449 | 450 | // @Test void testGenerateList() 451 | // { 452 | // Integer[] ints = {1,2,3,4,5}; 453 | // Observable observableList = Observable.from(ints); 454 | // List list = observableList.extend() 455 | // } 456 | 457 | @Test 458 | public void testMergeWith() { 459 | Observable first = Observable.just("aaaa", "bbbb", "ccc", "dddd"); 460 | Observable second = Observable.just("11111", "2222", "3333", "4444", "555555"); 461 | for (int i = 0; i < 10; i++) { 462 | Observable combined = first.mergeWith(second); 463 | combined.subscribe(System.out::println); 464 | System.out.println(); 465 | } 466 | } 467 | 468 | @Test 469 | public void testFlatMap() { 470 | Observable observable = Observable.just("aaaa", "bbbb", "ccc", "dddd"); 471 | Observable flatMap = observable.flatMap(a -> Observable.just("flat mapped:" + a)); 472 | Observable map = observable.map(a -> "mapped:" + a); 473 | 474 | Action1 action = (x) -> System.out.println(x.getClass() + ":" + x + ":" + x.hashCode()); 475 | observable.subscribe(action); 476 | 477 | System.out.println(); 478 | flatMap.subscribe(action); 479 | 480 | System.out.println(); 481 | map.subscribe(action); 482 | } 483 | 484 | @Test 485 | public void testSingle() { 486 | // merge a & b into an Observable stream of 2 values 487 | Single firstString = Single.create(o -> o.onSuccess("DataA")); 488 | Single secondString = Single.just("DataB"); 489 | Observable merged = firstString.mergeWith(secondString); 490 | merged.subscribe(System.out::println); 491 | } 492 | 493 | @Test 494 | public void testObserver() { 495 | Observable observable = Observable.just("aaaa", "bbbb", "ccc", "dddd"); 496 | observable.subscribe(new Action1() { 497 | @Override 498 | public void call(String x) { 499 | System.out.println(x); 500 | } 501 | }, new Action1() { 502 | @Override 503 | public void call(Throwable x1) { 504 | System.out.println(x1); 505 | } 506 | }, new Action0() { 507 | @Override 508 | public void call() { 509 | System.out.println(); 510 | } 511 | }); 512 | } 513 | 514 | @Test 515 | public void testSubscripion() { 516 | 517 | 518 | } 519 | 520 | @Test 521 | public void testTimer() { 522 | Observable 523 | .timer(5000, TimeUnit.MILLISECONDS) 524 | .subscribe(System.out::println); 525 | sleep(5000); 526 | } 527 | 528 | @Test 529 | public void testInterval() { 530 | Observable.interval(1, TimeUnit.SECONDS) 531 | .subscribe(System.out::println); 532 | sleep(5000); 533 | } 534 | 535 | 536 | @Test 537 | public void testColdObservable() throws InterruptedException { 538 | Observable observable = 539 | Observable.interval(1, TimeUnit.SECONDS); 540 | 541 | observable.subscribe( 542 | val -> System.out.println("Subscriber 1>> " + val)); 543 | 544 | sleep(3000); 545 | 546 | observable.subscribe( 547 | val -> System.out.println("Subscriber 2>> " + val)); 548 | 549 | sleep(5000); 550 | } 551 | 552 | 553 | @Test 554 | public void testHotObservable() throws InterruptedException { 555 | Observable observable = 556 | Observable.interval(1, TimeUnit.SECONDS).publish(); 557 | 558 | observable.subscribe( 559 | val -> System.out.println("Subscriber 1>> " + val)); 560 | 561 | ((ConnectableObservable) observable).connect(); 562 | 563 | sleep(3000); 564 | observable.subscribe( 565 | val -> System.out.println("Subscriber 2>> " + val)); 566 | 567 | sleep(5000); 568 | } 569 | 570 | @Test 571 | public void test_fibonacci() { 572 | Observable fibonacci = Observable.create( 573 | observer -> { 574 | int f1 = 0, f2 = 1, f = 1; 575 | while (!observer.isUnsubscribed()) { 576 | observer.onNext(f); 577 | System.out.println(f); 578 | f = f1 + f2; 579 | f1 = f2; 580 | f2 = f; 581 | } 582 | } 583 | ); 584 | 585 | Observable evenFibs = fibonacci 586 | .take(10) 587 | // .takeWhile(s -> s <= 4_000_000) 588 | // .filter(s -> s % 2 == 0) 589 | .doOnNext(System.out::println) 590 | .reduce(0, (a, b) -> a + b); 591 | evenFibs.subscribe(System.out::println); 592 | } 593 | 594 | @Test 595 | public void testFib2() { 596 | Observable.just(0).repeat(); 597 | final int[] first = {0}; 598 | final int[] second = {1}; 599 | Observable.range(1, 10) 600 | .scan((a, b) -> { 601 | int hold = second[0]; 602 | second[0] = second[0] + first[0]; 603 | first[0] = hold; 604 | return second[0]; 605 | }) 606 | .subscribe(System.out::println); 607 | } 608 | 609 | @Test 610 | public void testMergeIdentical() 611 | { 612 | ConnectableObservable hot = Observable.interval(1, TimeUnit.SECONDS).publish(); 613 | hot.connect(); 614 | hot.mergeWith(hot).subscribe((x) -> System.out.println(System.nanoTime() + " " + x)); 615 | 616 | sleep(50_000); 617 | 618 | } 619 | 620 | 621 | @Test 622 | public void testConcurrent() { 623 | Observable a = Observable.create(s -> { 624 | new Thread(() -> { 625 | s.onNext("one"); 626 | s.onNext("two"); 627 | s.onNext("three"); 628 | s.onNext("four"); 629 | s.onNext("five"); 630 | s.onNext("six"); 631 | s.onNext("seven"); 632 | s.onNext("eight"); 633 | s.onNext("nine"); 634 | s.onNext("ten"); 635 | s.onNext(""); 636 | s.onCompleted(); 637 | }).start(); 638 | }); 639 | 640 | Observable b = Observable.create(s -> { 641 | new Thread(() -> { 642 | s.onNext("HELLO"); 643 | s.onNext("THERE"); 644 | s.onNext(""); 645 | s.onCompleted(); 646 | }).start(); 647 | }); 648 | 649 | // this subscribes to a and b concurrently, and merges into a third sequential stream 650 | Observable c = Observable.merge(a, b); 651 | 652 | c.subscribe(System.out::println); 653 | sleep(3000); 654 | } 655 | 656 | 657 | @Test 658 | public void testCompletable() { 659 | Completable.create((Completable.OnSubscribe) s -> System.out.println(s)); 660 | } 661 | 662 | private static void sleep(long value) { 663 | try { 664 | Thread.sleep(value); 665 | } catch (InterruptedException e) { 666 | Thread.currentThread().interrupt(); 667 | } 668 | } 669 | } 670 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/MapFlatMapExamples.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | import org.junit.Test; 4 | import rx.Observable; 5 | 6 | import static com.vgrazi.play.MapFlatMapExamples.Sound.BLANK; 7 | import static com.vgrazi.play.MapFlatMapExamples.Sound.DAH; 8 | import static com.vgrazi.play.MapFlatMapExamples.Sound.DI; 9 | import static rx.Observable.empty; 10 | import static rx.Observable.just; 11 | 12 | /** 13 | * Created by victorg on 7/28/2016. 14 | */ 15 | public class MapFlatMapExamples { 16 | @Test 17 | public void testMap() { 18 | Observable tweets = Observable.just("learning RxJava", "Writing blog about RxJava", "RxJava rocks!!"); 19 | tweets.map(tweet -> tweet.length()).forEach(System.out::println); 20 | } 21 | 22 | @Test 23 | public void testFlatMap() { 24 | Observable tweets = Observable.just("learning RxJava", "Writing blog about RxJava", "RxJava rocks!!"); 25 | tweets.flatMap(tweet -> Observable.from(tweet.split(""))).forEach(System.out::println); 26 | } 27 | 28 | Observable toMorseCode(char ch) { 29 | switch (ch) { 30 | case 'a': 31 | return just(DI, DAH, BLANK); 32 | case 'b': 33 | return just(DAH, DI, DI, DI, BLANK); 34 | case 'c': 35 | return just(DAH, DI, DAH, DI, BLANK); 36 | //... 37 | case 'p': 38 | return just(DI, DAH, DAH, DI, BLANK); 39 | case 'r': 40 | return just(DI, DAH, DI, BLANK); 41 | case 's': 42 | return just(DI, DI, DI, BLANK); 43 | case 't': 44 | return just(DAH, BLANK); 45 | //... 46 | default: 47 | return empty(); 48 | } 49 | } 50 | 51 | @Test 52 | public void testMorseCode() { 53 | Observable just = just('S', 'p', 'a', 'r', 't', 'a'); 54 | Observable soundObservable = just 55 | .map(Character::toLowerCase) 56 | .flatMap(this::toMorseCode); 57 | soundObservable.subscribe(System.out::print); 58 | } 59 | 60 | enum Sound { 61 | DI, DAH, BLANK; 62 | 63 | @Override 64 | public String toString() { 65 | if(this == BLANK) { 66 | return " "; 67 | } 68 | else { 69 | return super.toString(); 70 | } 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/MathExamples.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | import org.junit.Test; 4 | import rx.Observable; 5 | import rx.Subscriber; 6 | import rx.functions.Func1; 7 | import rx.observables.ConnectableObservable; 8 | import rx.observables.MathObservable; 9 | 10 | import java.util.Arrays; 11 | import java.util.List; 12 | import java.util.concurrent.ThreadFactory; 13 | import java.util.concurrent.TimeUnit; 14 | 15 | import static rx.observables.MathObservable.*; 16 | 17 | /** 18 | * Created by vgrazi on 7/31/16. 19 | */ 20 | public class MathExamples { 21 | static Observable> sequence = Observable.create(new Observable.OnSubscribe>() { 22 | @Override 23 | public void call(Subscriber> subscriber) { 24 | subscriber.onNext(Arrays.asList(10, 9, 8, null, 1, 2, 3, 4)); 25 | subscriber.onCompleted(); 26 | } 27 | }); 28 | 29 | 30 | @Test 31 | public void testMin() { 32 | Observable rObservable = sequence 33 | .filter(number -> number != null) 34 | .flatMap(numList -> Observable.from(numList) 35 | // .min 36 | ); 37 | rObservable.subscribe(System.out::println); 38 | 39 | } 40 | 41 | @Test 42 | public void testReduce() { 43 | Observable rObservable = sequence 44 | .flatMap(numList -> Observable.from(numList) 45 | .filter(number -> number != null) 46 | // .timeInterval() 47 | // .reduce(Integer.MAX_VALUE, (currentMin, number) -> number < currentMin ? number : currentMin) 48 | .reduce(Integer.MIN_VALUE, (currentMax, number) -> number > currentMax ? number : currentMax) 49 | .filter(number -> number != Integer.MIN_VALUE) 50 | ); 51 | rObservable.subscribe(System.out::println); 52 | } 53 | 54 | public static void main(String[] args) throws InterruptedException { 55 | // ConnectableObservable observable = Observable.interval(1, TimeUnit.SECONDS).publish(); 56 | // observable.connect(); 57 | // Observable observable = Observable.interval(1, TimeUnit.SECONDS); 58 | sequence 59 | .filter(x->x != null) 60 | // .map(aLong -> (double)aLong) 61 | // .window(100, TimeUnit.MILLISECONDS) 62 | // .flatMap(MathObservable::averageInteger) 63 | .subscribe(System.out::println, Throwable::printStackTrace); 64 | 65 | 66 | Thread.sleep(10_000); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/PriceTick.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | import java.text.DecimalFormat; 4 | import java.text.NumberFormat; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | 8 | public class PriceTick { 9 | private final int sequence; 10 | private final Date date; 11 | private final String instrument; 12 | private final double price; 13 | private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("hh:mm:ss"); 14 | 15 | 16 | public PriceTick(int sequence, Date date, String instrument, double price) { 17 | this.sequence = sequence; 18 | this.date = date; 19 | this.instrument = instrument; 20 | this.price = price; 21 | } 22 | 23 | public int getSequence() { 24 | return sequence; 25 | } 26 | 27 | public Date getDate() { 28 | return date; 29 | } 30 | 31 | public String getInstrument() { 32 | return instrument; 33 | } 34 | 35 | public double getPrice() { 36 | return price; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return String.format("%6d %s %s %s", sequence, DATE_FORMAT.format(new Date()), instrument, price); 42 | } 43 | 44 | public boolean isLast() { 45 | return false; 46 | // return sequence >= 10; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/SomeFeed.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | import com.vgrazi.util.Utils; 4 | 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | import java.util.Random; 10 | import java.util.concurrent.BrokenBarrierException; 11 | import java.util.concurrent.CyclicBarrier; 12 | import java.util.concurrent.ExecutorService; 13 | import java.util.concurrent.Executors; 14 | import java.util.concurrent.atomic.AtomicInteger; 15 | 16 | public class SomeFeed { 17 | private final boolean barriered; 18 | private AtomicInteger threadcounter = new AtomicInteger(1); 19 | 20 | private ExecutorService service = Executors.newCachedThreadPool(r -> { 21 | Thread thread = new Thread(r); 22 | thread.setName("Thread " + threadcounter.getAndIncrement()); 23 | return thread; 24 | }); 25 | private transient boolean running = true; 26 | 27 | private List listeners = new LinkedList<>(); 28 | private int threadCount; 29 | private CyclicBarrier barrier; 30 | 31 | private final Random RANDOM = new Random(0); 32 | private static final Random RANDOM_PRICE = new Random(0); 33 | 34 | private static final String[] instruments = {"IBM", "NMR", "BAC", "AAPL", "MSFT"}; 35 | 36 | public SomeFeed() { 37 | this(instruments.length); 38 | } 39 | 40 | public SomeFeed(int threadCount) { 41 | this(threadCount, false); 42 | } 43 | 44 | public SomeFeed(int threadCount, boolean barriered) { 45 | this.threadCount = threadCount; 46 | this.barriered = barriered; 47 | if (barriered) { 48 | barrier = new CyclicBarrier(threadCount, System.out::println); 49 | } 50 | launchPublishers(); 51 | } 52 | 53 | 54 | AtomicInteger sequence = new AtomicInteger(1); 55 | private void launchEventThread(String instrument, double startingPrice) { 56 | service.execute(() -> 57 | { 58 | final Object MUTEX = new Object(); 59 | SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss.SSS"); 60 | double price = startingPrice; 61 | while (running) { 62 | try { 63 | if (barriered) { 64 | barrier.await(); 65 | } 66 | price += RANDOM_PRICE.nextGaussian(); 67 | 68 | double finalPrice = price; 69 | listeners.forEach(subscriber -> { 70 | PriceTick tick = new PriceTick(sequence.getAndIncrement(), new Date(), instrument, finalPrice); 71 | String message = String.format("%s %s %s", format.format(new Date()), instrument, finalPrice); 72 | // Logger.print("Notifying " + message); 73 | subscriber.priceTick(tick); 74 | }); 75 | synchronized (MUTEX) { 76 | MUTEX.wait(RANDOM.nextInt(200) + 800); 77 | } 78 | } catch (InterruptedException | BrokenBarrierException e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | }); 83 | } 84 | 85 | double[] prices = {160, 5, 15, 108, 57}; 86 | void launchPublishers() { 87 | Utils.print("Launching publishers"); 88 | for (int i = 0; i < threadCount; i++) { 89 | launchEventThread(instruments[i%instruments.length], prices[i%prices.length]); 90 | } 91 | } 92 | 93 | public void register(SomeListener listener) { 94 | Utils.print("Registering subscriber " + listener); 95 | listeners.add(listener); 96 | } 97 | 98 | public void terminate() { 99 | running = false; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/SomeListener.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | import java.util.concurrent.atomic.AtomicInteger; 4 | 5 | /** 6 | * Created by victorg on 7/27/2016. 7 | */ 8 | public abstract class SomeListener { 9 | private static final AtomicInteger COUNTER = new AtomicInteger(1); 10 | private final int ID; 11 | public SomeListener() 12 | { 13 | ID = COUNTER.getAndIncrement(); 14 | } 15 | 16 | public abstract void priceTick(PriceTick event); 17 | public abstract void error(Throwable throwable); 18 | 19 | @Override 20 | public String toString() { 21 | return String.format("Listener ID:%d:%s", ID, super.toString()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/play/reactive.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.play; 2 | 3 | 4 | import org.junit.Test; 5 | import rx.Observable; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | /** 12 | * Created by victorg on 7/13/2016. 13 | */ 14 | @SuppressWarnings("UnnecessaryLocalVariable") 15 | public class reactive { 16 | public static void main(String[] args) { 17 | Observable.just(8, 9, 10) 18 | .doOnNext(i -> System.out.println("A:" + i)) 19 | .filter(i -> i % 3 > 0) 20 | .doOnNext(i -> System.out.println("B:" + i)) 21 | .map(i -> "#" + i * 10) 22 | .doOnNext(i -> System.out.println("C:" + i)) 23 | .filter(s -> s.length() < 4) 24 | .doOnNext(i -> System.out.println("D-:" + i)) 25 | .subscribe(s -> System.out.println("D:" + s)) 26 | ; 27 | 28 | } 29 | 30 | @Test 31 | public void test() { 32 | Observable.just(2, 4, 6) 33 | .doOnNext(System.out::println) 34 | .subscribe(); 35 | 36 | } 37 | 38 | private List wordList = Arrays.asList("Adam", "Dog", "cat", null, "this", "is", "a", "test"); 39 | 40 | @Test 41 | public void test1() { 42 | Observable.from(wordList) 43 | .filter(s -> s.length() > 2) 44 | .map(s -> s + ": " + s.length()) 45 | .subscribe(s -> System.out.println(s)); 46 | } 47 | 48 | 49 | private Observable query(String param) { 50 | Observable query = Observable.from(wordList); 51 | return query; 52 | } 53 | 54 | @Test 55 | public void testWordFlatMap() { 56 | 57 | query("Hello world") 58 | .flatMap(Observable::just) 59 | .subscribe(System.out::println); 60 | } 61 | 62 | // @Test 63 | // public void testDelay() 64 | // { 65 | // Observable.range(1,10) 66 | // .delay(, TimeUnit.SECONDS) 67 | // } 68 | 69 | @Test 70 | public void testIntList() { 71 | Observable.range(1, 10) 72 | .flatMap(v -> Observable.just(v) 73 | .delay(11 - v, TimeUnit.SECONDS)) 74 | .toBlocking() 75 | .subscribe(System.out::println); 76 | } 77 | @Test 78 | public void testRange() { 79 | 80 | Observable range = Observable.range(1, 9); 81 | range.flatMap((s -> Observable.just(s) 82 | .doOnNext(System.out::println) 83 | .delay(10 - s, TimeUnit.SECONDS)) 84 | ) 85 | .toBlocking() 86 | .subscribe(System.out::println); 87 | } 88 | 89 | @Test 90 | public void testComposition() 91 | { 92 | query("Hello, world!") 93 | .filter(url -> url != null) 94 | .flatMap(this::getTitle) 95 | .take(5) 96 | .subscribe(System.out::println); } 97 | 98 | private Observable getTitle(String url) 99 | { 100 | return Observable.just(String.format("Title:%s", url)); 101 | } 102 | 103 | } -------------------------------------------------------------------------------- /src/main/java/com/vgrazi/util/Utils.java: -------------------------------------------------------------------------------- 1 | package com.vgrazi.util; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Calendar; 6 | import java.util.Date; 7 | 8 | /** 9 | * Created by vgrazi on 9/2/16. 10 | */ 11 | public class Utils { 12 | public static void print(Object s) { 13 | System.out.printf("%s:%s%n", new Date(), s); 14 | } 15 | 16 | public static void sleep(long time) { 17 | try { 18 | Thread.sleep(time); 19 | } catch (InterruptedException e) { 20 | e.printStackTrace(); 21 | } 22 | } 23 | 24 | private static long start = System.currentTimeMillis(); 25 | 26 | public static Boolean isSlowTime() { 27 | boolean b = (System.currentTimeMillis() - start) % 30_000 >= 15_000; 28 | // System.out.println(new Date() + String.format("is %sslow time", b?"":"NOT ")); 29 | return b; 30 | } 31 | 32 | @Test 33 | public void test() { 34 | while (true) { 35 | System.out.println(String.format(new Date() + " is %sslow time ", isSlowTime() ? "" : "NOT ")); 36 | sleep(1_00); 37 | } 38 | } 39 | 40 | } 41 | --------------------------------------------------------------------------------