手寫 RxJava ---- map 操作符

一缤言、實現(xiàn)的思路

RxJava 提供了很多的變換操作符,將上游的數(shù)據(jù)轉(zhuǎn)換成另一種數(shù)據(jù)宝当,可以在傳送數(shù)據(jù)流的過程中構(gòu)造一個新的類,這個類即持有上游的 Observable 也持有下游的 Observer 和 變換的能力來實現(xiàn)

二胆萧、具體代碼

1.創(chuàng)建 map 操作符

map 操作符本身持有 ObservableOnSubscribe 對象庆揩,這里將 ObservableOnSubscribe 交給一個 ObservableMap 讓它持有了上游的能力。同時也持有了變換的能力

  /**
     * 自定義 map 操作符
     * map 操作符會拿到 SelfObservableMap 所持有的 Observable 對象
     * 交給一個 ObservableMap 對象 然后替換一個新的(持有 ObservableMap 這個 ObservableOnSubscribe 的引用跌穗,已經(jīng)一個轉(zhuǎn)換的函數(shù))
     * 即擁有控制上一層的能力 也擁有控制下一層的能力
     * <p>
     * 變換操作符只考慮上一層的類型 變換成新的類型后 給到下一層
     */
    public <R> SelfObserverable<R> map(CFunction<? super T, R> function) {
        ObservableMap observableMap = new ObservableMap(observable, function);
        // 這里會把 source 替換成 ObservableMap
        // 在 subscribe 時實際調(diào)用的 observable map 所持有的 source 的 subscribe 方案
        return new SelfObserverable<>(observableMap);
    }

2.ObservableMap 同時提供了 subscribe 函數(shù)订晌,讓它持有了下游的能力

/**
 * 為 Map 專門定義的 ObservableOnSubscribe
 * T 接收的類型 R 返回的類型
 *
 */
public class ObservableMap<T,R> implements ObservableOnSubscribe<R> {
    // 這里持有的是第一次通過 create 函數(shù)創(chuàng)建持有的 ObservableOnSubscribe 對象
    private ObservableOnSubscribe observable;
    private CFunction<? super T, ? extends R> function;

    public ObservableMap(ObservableOnSubscribe source, CFunction<? super T, ? extends R> function) {
        this.observable = source;
        this.function = function;
    }

    /**
     * observableEmitter 是外層通過 subscribe 函數(shù)傳遞進來的 Observer 類
     * @param observer
     */
    @Override
    public void subscribe(Observer<? super R> observer) {
        // SelfObserverable 調(diào)用 subscribe 函數(shù)時 實際上調(diào)用的是
        MapObserver mapObserver = new MapObserver(observer,  function);
        // observable 是通過 create 或者 just 傳遞進來的 observable,現(xiàn)在交給了它一個 MapObserver
        /**
         *     observable ----> create 的 new ObservableOnSubscribe
         *     // 使用 Map 操作符
         *     SelfObserverable.create(new ObservableOnSubscribe<Integer>() {
         *      @Override
         *      public void subscribe(Observer<? super Integer> observableEmitter) {
         *            observableEmitter.onNext(1);
         *            observableEmitter.onComplete();
         *         }
         *     })
         *
         *    這個 observable.subscribe 調(diào)用的就是 ObservableOnSubscribe 的 subscribe 函數(shù)的方法瞻离。
         *    會觸發(fā) MapObserver 類的 onNext 和 onComplete
         */
        observable.subscribe(mapObserver);
    }

3.在 subscribe 時又對 observer 做了進一步的包裝,讓被觀察者 ObservableOnSubscribe 持有了 MapObserver 這個新的觀察者類腾仅。在調(diào)用 onNext 時首先調(diào)用 CFunction 函數(shù)進行一次數(shù)據(jù)轉(zhuǎn)換

 /**
     * 對 Observer 的包裝
     *
     * @param <T>
     */
    class MapObserver<T> implements Observer<T> {
        Observer<? super R> observableEmitter;
        ObservableOnSubscribe source;
        CFunction<? super T, ? extends R> function;

        /**
         *
         * @param observableEmitter  通過 subscribe 傳遞進來的觀察者
         * @param function function 是負(fù)責(zé)轉(zhuǎn)換的函數(shù)
         */
        public MapObserver(Observer<? super R> observableEmitter,
                           CFunction<? super T, ? extends R> function) {
            this.observableEmitter = observableEmitter;
            this.function = function;
        }

        @Override
        public void onSubscirbe() {
            observableEmitter.onSubscirbe();
        }

        @Override
        public void onNext(T value) {
            // 將轉(zhuǎn)換后的值交給 onNext
            R next = function.apply(value);
            observableEmitter.onNext(next);
        }

        @Override
        public void onComplete() {
            observableEmitter.onComplete();
        }

        @Override
        public void onError(Throwable throwable) {
            observableEmitter.onError(throwable);
        }
    }

四、流程示例

RxJava-2.jpg

五套利、使用示例

  // 使用 Map 操作符
        SelfObserverable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(Observer<? super Integer> observableEmitter) {
                observableEmitter.onNext(1);
                observableEmitter.onComplete();
            }
        }).map(new CFunction<Integer, String>() {

            @Override
            public String apply(Integer integer) {
                return "我被轉(zhuǎn)換啦";
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscirbe() {
                Log.d("TAG", "on subscribe with map");
            }

            @Override
            public void onNext(String value) {
                Log.d("TAG", "我被轉(zhuǎn)換啦");
            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onError(Throwable throwable) {

            }
        });
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鹤耍,隨后出現(xiàn)的幾起案子肉迫,更是在濱河造成了極大的恐慌,老刑警劉巖稿黄,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喊衫,死亡現(xiàn)場離奇詭異,居然都是意外死亡杆怕,警方通過查閱死者的電腦和手機族购,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門壳贪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人寝杖,你說我怎么就攤上這事违施。” “怎么了瑟幕?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵磕蒲,是天一觀的道長。 經(jīng)常有香客問我只盹,道長辣往,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任殖卑,我火速辦了婚禮站削,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘孵稽。我一直安慰自己许起,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布肛冶。 她就那樣靜靜地躺著街氢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪睦袖。 梳的紋絲不亂的頭發(fā)上珊肃,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音馅笙,去河邊找鬼伦乔。 笑死,一個胖子當(dāng)著我的面吹牛董习,可吹牛的內(nèi)容都是我干的烈和。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼皿淋,長吁一口氣:“原來是場噩夢啊……” “哼招刹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起窝趣,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤疯暑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后哑舒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妇拯,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年洗鸵,在試婚紗的時候發(fā)現(xiàn)自己被綠了越锈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仗嗦。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖甘凭,靈堂內(nèi)的尸體忽然破棺而出稀拐,到底是詐尸還是另有隱情,我是刑警寧澤对蒲,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布钩蚊,位于F島的核電站,受9級特大地震影響蹈矮,放射性物質(zhì)發(fā)生泄漏砰逻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一泛鸟、第九天 我趴在偏房一處隱蔽的房頂上張望蝠咆。 院中可真熱鬧,春花似錦北滥、人聲如沸刚操。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽菊霜。三九已至,卻和暖如春济赎,著一層夾襖步出監(jiān)牢的瞬間鉴逞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工司训, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留构捡,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓壳猜,卻偏偏與公主長得像勾徽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子统扳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容