/** * An {@link ObservableOperator} that enables the switch-case behavior in Rx-Java, it uses * a table look up technique to simulate a switch-case behavior *

* you must supply a {@link Map} that holds functions that will be executed if the emitted * item matches the key they are mapped to *

* if multiple emitted items matches several keys, all there functions will be executed and * will emit there results, if you want the first match to disable the rest of the checks, * you can use {@link SwitchCaseBreak} instead *

* sample code : *

* {@code List list = Arrays.asList(1, 2, 3, 4);}
* {@code Map> caseBlocks = new HashMap<>(2);}
* {@code caseBlocks.put(2, (i) -> "TWO SELECTED");}
* {@code caseBlocks.put(3, (i) -> "THREE SELECTED");}
*

* {@code Observable.fromIterable(list)}
* {@code .lift(new SwitchCase<>(caseBlocks))}
* {@code .subscribe(System.out::println);}
*

* // result :
* TWO SELECTED
* THREE SELECTED
* * @param the type of the items that will be passed to the {@code switch} statement * @param the type of the items that will be returned from the {@code case} block execution */ public class SwitchCase implements ObservableOperator { final Map> caseBlocks = new LinkedHashMap<>(); /** * create a {@link SwitchCase} operator, if any {@link Function} returned {@code null}, the * whole operation will crash * * @param caseBlocks the map that holds {@link Function} that are the case-blocks in this * switch-case */ public SwitchCase(@NonNull Map> caseBlocks) { if (caseBlocks != null) { this.caseBlocks.putAll(caseBlocks); } } @Override public Observer apply(final Observer observer) throws Exception { return createResultObserver(observer); } private Observer createResultObserver(final Observer observer) { return new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { } @Override public void onNext(@NonNull T switchOn) { Function block = Maybe.just(caseBlocks) .filter(map -> map.containsKey(switchOn)) .map(map -> map.get(switchOn)) .blockingGet(); if (block == null) { return; } try { invokeOnNext(observer, block.apply(switchOn)); } catch (Throwable e) { onError(e); } } @Override public void onError(@NonNull Throwable e) { observer.onError(e); } @Override public void onComplete() { observer.onComplete(); } }; } void invokeOnNext(Observer observer, R onNextValue) { observer.onNext(onNextValue); } }