RxJava系列之手写map操作符

系列文章

RxJava系列之简介和观察者设计模式
RxJava系列之上游与下游
RxJava系列之常用创建型操作符
RxJava系列之常用变换操作符
RxJava系列之常用过滤操作符
RxJava系列之常用条件操作符
RxJava系列之常用合并操作符
RxJava系列之常用异常操作符
RxJava系列之线程切换实战
RxJava系列之背压模式
RxJava系列之配合Retrofit
RxJava系列之泛型高级
RxJava系列之手写create操作符
RxJava系列之手写create操作符增加泛型限定
RxJava系列之手写just操作符
RxJava系列之手写map操作符
RxJava系列之手写切换线程

map操作符

map操作符是变换操作符,将上游的数据经过变换交给下游。所以内部肯定需要对上游操作,也要对下游操作。

Function

变换的标准,可以将T变换成R


public interface Function<T, R> {

    public R apply(T t); // 变换的行为标准

}

ObservableMap

负责与上游下游打交道的类。因为需要同时接收变换前的类型和变换后的类型,所以新建了ObservableOnSubscribe的子类。

// ObservableOnSubscribe 简称 source

public class ObservableMap<T, R> implements ObservableOnSubscribe<R> {

    private ObservableOnSubscribe<T> source; // 上一层的能力
    private Function<? super T, ? extends R> function;
    private Observer<? super R> observableEmitter; // 下一层的能力


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

    @Override
    public void subscribe(Observer<? super R> observableEmitter) {
        this.observableEmitter = observableEmitter;

        // source.subscribe(observableEmitter); // 不应该把下一层Observer交出去 ---》 上一层, 如果交出去了,map没有控制权

        MapObserver<T> mapObserver = new MapObserver(observableEmitter, source, function);

        source.subscribe(mapObserver); // 把我们自己 map MapObserver 交出去了
    }

    // 真正拥有控制下一层的能力  让map拥有控制权力  observer,source,function
    class MapObserver<T> implements Observer<T> {

        private Observer</*? super */R> observableEmitter; // 给下一层的类型,意思是 变换后的类型 也就是给下一层的类型 R
        private ObservableOnSubscribe<T> source;
        private Function<? super T, ? extends R> function;

        public MapObserver(Observer</*? super */R> observableEmitter,
                           ObservableOnSubscribe<T> source,
                           Function<? super T, ? extends R> function) {
            this.observableEmitter = observableEmitter;
            this.source = source;
            this.function = function;

        }

        @Override
        public void onSubscribe() {
            // observableEmitter.onSubscribe();
        }

        @Override
        public void onNext(T item) { // 真正做变换的操作

            /**
             * T Integer    变换     R String
             */

            R nextMapResultSuccesType = function.apply(item);

            // 调用下一层 onNext 方法
            observableEmitter.onNext(nextMapResultSuccesType);
        }

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

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

Observable增加map方法

/**
* map变换操作符
*
* T == 上一层传递过来的类型 Integer 变换前的类型
* R == 给一层的类型 String 变换后的类型
*
*/
public Observable map(Function<? super T, ? extends R> function) { // ? super T 可写模式

    ObservableMap<T, R> observableMap = new ObservableMap(source, function); // source 上一层的能力

    return new Observable<R>(observableMap); // source  该怎么来?     observableMap是source的实现类
}

测试代码

// TODO map变换操作符 RxJava的核心
        // 上游
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(Observer<? super Integer> observableEmitter) { // 使用到了,就产生了读写模式
                Log.d(TAG, "subscribe: 上游开始发射...");
                // 发射事件  可写的
                // todo 使用者去调用发射 2
                observableEmitter.onNext(9); //  <? extends Integer> 不可写了   <? super Integer>可写
                observableEmitter.onComplete();
            }
        })

        .map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                Log.d(TAG, "第1个变换 apply: " + integer);
                return "【" + integer + "】";
            }
        })

        .map(new Function<String, StringBuffer>() {
            @Override
            public StringBuffer apply(String s) {
                Log.d(TAG, "第2个变换 apply: " + s);
                return new StringBuffer().append(s).append("-----------------------");
            }
        })

        // Observable<Integer>.subscribe
        .subscribe(new Observer<StringBuffer>() { // 下游
             // 接口的实现方法
             @Override
             public void onSubscribe() {
                 // todo 1
                 Log.d(TAG, "已经订阅成功,即将开始发射 onSubscribe: ");
             }

             // 接口的实现方法
             @Override
             public void onNext(StringBuffer item) {
                 // todo 3
                 Log.d(TAG, "下游接收事件 onNext: " + item); // 【9】-----------------------
             }

             // 接口的实现方法
             @Override
             public void onError(Throwable e) {

             }

             // 接口的实现方法
             @Override
             public void onComplete() {
                 // todo 4 最后一步
                 Log.d(TAG, "onComplete: 下游接收事件完成√√√√√√√√√√√√√√");
             }
            });

流程梳理

在这里插入图片描述
1.订阅subscribe方法,将下游Observer对象传入到map操作符创建出来的Observable对象的subscribe方法中

2.根据Observable的subscribe方法的定义,会先执行下游Observer的onSubscribe方法,然后将Observer交给source.subscribe方法。因为map操作符的source重写了,所以使用的是ObservableMap这个对象的subscribe方法

 @Override
    public void subscribe(Observer<? super T> observableEmitter) { // == Observer 
        observableEmitter.onSubscribe(); 
        source.subscribe(observableEmitter); // 这个source就有了  观察者 Observer
    }

3.ObservableMap的构造方法会将上游Observable的source,变换规则Function传入,并缓存到全局变量中

private ObservableOnSubscribe<T> source; // 上一层的能力
private Function<? super T, ? extends R> function;

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

4.ObservableMap的subscribe方法

 @Override
    public void subscribe(Observer<? super R> observableEmitter) {
     // observableEmitter == 最右边的观察者
        // 包裹一层  然后再丢给我们的 最顶层的source
        MapObserver<T> mapObserver = new MapObserver(observableEmitter, function);
        // 上一层的source
        source.subscribe(mapObserver); // 把我们自己 map MapObserver 交出去了
    }

MapObserver是Observer的子类,在构造方法中将下游的Observer对象和变换规则对象缓存到全局变量中。

class MapObserver<T> implements Observer<T> {

    private Observer</*? super */R> observableEmitter;
    private Function<? super T, ? extends R> function;

 

    public MapObserver(Observer</*? super */R> observableEmitter,
        Function<? super T, ? extends R> function) {
        this.observableEmitter = observableEmitter;
        this.function = function;

    }
}

5.将下游的Observer对象又包裹了一层,成为MapObserver对象,然后交给上游source.subscribe去执行。

6.这个上游的source.subscribe就会走到create的时候传入的那个source的subscribe。

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(Observer<? super Integer> observableEmitter) { 

        Log.d(TAG, "subscribe: 上游开始发射...");
        // 发射事件  可写的
        observableEmitter.onNext(9);
        observableEmitter.onComplete();
    }
})

7.这里发送的onNext,onComplete事件,都将被MapObserver接收,因为调用这个方法的时候传入的是MapObserver的对象。
8.MapObserver接收到事件之后,先做转换工作,然后调用下游Observer的方法。

		@Override
        public void onNext(T item) { 
            // 真正做变换的操作
            R nextMapResultSuccesType = function.apply(item);
            // 调用下一层 onNext 方法
            observableEmitter.onNext(nextMapResultSuccesType);
        }

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

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

9.下游Observer对象接收到事件

subscribe(new Observer<StringBuffer>() { // 下游
             @Override
             public void onSubscribe() {
                 Log.d(TAG, "已经订阅成功,即将开始发射 onSubscribe: ");
             }
                   
             @Override
             public void onNext(StringBuffer item) {
                 Log.d(TAG, "下游接收事件 onNext: " + item); 
             }
  
             @Override
             public void onError(Throwable e) {
             }
             
             @Override
             public void onComplete() {
                 Log.d(TAG, "onComplete: 下游接收事件完成√√√√√√√√√√√√√√");
             }
        });

这样最终事件就被Map先做了处理,然后交由下游,map的整体流程也分析结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的基于链表实现的Map类示例,你可以参考一下: ```c++ #include <iostream> #include <string> using namespace std; template <typename KeyType, typename ValueType> class Map { private: struct Node { KeyType key; ValueType value; Node* next; Node(const KeyType& k, const ValueType& v) : key(k), value(v), next(nullptr) {} }; Node* head; public: Map() : head(nullptr) {} ~Map() { Node* node = head; while (node != nullptr) { Node* next = node->next; delete node; node = next; } } void insert(const KeyType& k, const ValueType& v) { Node* node = head; while (node != nullptr) { if (node->key == k) { node->value = v; return; } node = node->next; } node = new Node(k, v); node->next = head; head = node; } const ValueType& operator[](const KeyType& k) const { Node* node = head; while (node != nullptr) { if (node->key == k) { return node->value; } node = node->next; } throw "Key not found!"; } bool contains(const KeyType& k) const { Node* node = head; while (node != nullptr) { if (node->key == k) { return true; } node = node->next; } return false; } }; int main() { Map<string, int> myMap; myMap.insert("apple", 3); myMap.insert("banana", 6); myMap.insert("cherry", 9); cout << myMap["apple"] << endl; // 3 cout << myMap["banana"] << endl; // 6 cout << myMap["cherry"] << endl; // 9 cout << myMap["durian"] << endl; // throws "Key not found!" if (myMap.contains("apple")) { cout << "myMap contains 'apple'" << endl; } if (!myMap.contains("durian")) { cout << "myMap does not contain 'durian'" << endl; } return 0; } ``` 在这个示例中,我们使用了一个简单的单向链表来存储键值对。Map类提供了三个基本的操作:insert、operator[]和contains。insert操作将一个键值对插入到链表中,如果键已经存在,则更新对应的值。operator[]操作用于获取特定键的值,如果键不存在,则抛出异常。contains操作用于检查特定键是否存在于Map中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值