Rxjava2.0学习笔记(二)

吐槽

昨天学啊学,感觉头都炸了,这块感觉真的是很难受,但是自己的当前的目标是学会Rxjava+Retrofit结合在一起的网络框架套路,然后用到项目里面。自己的卡片项目也要加油,今天去和后台交流下。

Rxjava里面的线程问题

普通没有设置的时候,上游和下游(观察者和被观察者)在一个线程里面
但是
这样的话好多操作就完成不了,这样就很尴尬了
所以可以指定上游和下游的线程

Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            Log.d("233", "Observable thread is : " + Thread.currentThread().getName());
            Log.d("233", "emit 1");
            e.onNext(1);

        }
    });

    Consumer<Integer> consumer = new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            Log.d("233", "Observer thread is :" + Thread.currentThread().getName());
            Log.d("233", "onNext: " + integer);
        }
    };

    observable.subscribeOn(Schedulers.newThread())//上游指定的发送事件的线程
            .observeOn(AndroidSchedulers.mainThread())//下游指定的接收的线程
            .subscribe(consumer);

}

注意

  • subscribeOn() 指定的是上游发送事件的线程, observeOn() 指定的是下游接收事件的线程.
  • 多次指定上游的线程只有第一次指定的有效, 也就是说多次调用subscribeOn() 只有第一次的有效, 其余的会被忽略
  • 多次指定下游的线程是可以的, 也就是说每调用一次observeOn() , 下游的线程就会切换一次

在RxJava中, 已经内置了很多线程选项供我们选择
chedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作
Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作
Schedulers.newThread() 代表一个常规的新线程
AndroidSchedulers.mainThread() 代表Android的主线程

Rxjava2.0的操作符

这里写图片描述
这块东西很多唉。自己就简单看大佬的博客,学了几种常用的,其他的以后有用再说

Map操作符

map是RxJava中最简单的一个变换操作符了, 它的作用就是对上游发送的每一个事件应用一个函数, 使得每一个事件都按照指定的函数去变化.
就是把上游的东西转化成自己规定的东西
这里写图片描述
看代码例子

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        e.onNext(1);
        e.onNext(2);
        e.onNext(3);
    }
}).map(new Function<Integer, String>() {
    @Override
    public String apply(Integer integer) throws Exception {
        return "This is result" + integer;
    }
}).subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.d("233",s);
    }
});

结果
这里写图片描述
上游本来是发了3个int的事件,然后用Map转换为string类型,发给下游
就是个中转站

FlatMap操作符

FlatMap将一个发送事件的上游Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里.
这样说起来很绕口,就是把上游的发的一个事件,可以改变这个事件的数量和格式
这里写图片描述

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        e.onNext(1);
        e.onNext(2);
        e.onNext(3);
    }
}).flatMap(new Function<Integer, ObservableSource<String>>() {
    @Override
    public ObservableSource<String> apply(Integer integer) throws Exception {
        final List<String> list = new ArrayList<>();
        for (int i = 0;i < 3;i++){
            list.add("value "+integer);
        }
        return Observable.fromIterable(list).delay(50, TimeUnit.MICROSECONDS);
    }
}).subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.d("233",s);
    }
});

结果:
就是把发送的数据3个int类型的
每一个都变成3个String类型的
然后给下游接收到
//但是发送的时候顺序可能不一样

concatMap操作符

flatMap的作用几乎一模一样, 只是它的结果是严格按照上游发送的顺序来发送的

Zip操作符

通过一个函数将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件. 它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。
就是把两个上游的数据整合在一起,然后发给下游。
这里写图片描述
但是直接这样操作就很有问题

Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        Log.d("233","emit 1");
        e.onNext(1);
        Log.d("233","emit 2");
        e.onNext(2);
        Log.d("233","emit 3");
        e.onNext(3);
        Log.d("233","emit 4");
        e.onNext(4);
        Log.d("233","emit complete1");
        e.onComplete();
    }
});

Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        Log.d("233","emit A");
        e.onNext("A");
        Log.d("233","emit B");
        e.onNext("B");
        Log.d("233","emit C");
        e.onNext("C");
        Log.d("233","emit complete2");
        e.onComplete();
    }
});
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
    @Override
    public String apply(Integer integer, String s) throws Exception {
        return integer + s;
    }
}).subscribe(new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d("233","onSubscribe");
    }

    @Override
    public void onNext(String value) {
        Log.d("233","onNext"+value);

    }

    @Override
    public void onError(Throwable e) {
        Log.d("233","OnErron");

    }

    @Override
    public void onComplete() {
        Log.d("233","oncomplete");

    }
});

结果:
这里写图片描述
发现这个有问题
水管一发,水管2后发
所以为了解决这个问题
我们就开两个线程就好了

Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        Log.d("233","emit 1");
        e.onNext(1);
        Thread.sleep(1000);

        Log.d("233","emit 2");
        e.onNext(2);
        Thread.sleep(1000);
        Log.d("233","emit 3");
        e.onNext(3);
        Thread.sleep(1000);
        Log.d("233","emit 4");
        e.onNext(4);
        Thread.sleep(1000);
        Log.d("233","emit complete1");
        e.onComplete();
    }
}).subscribeOn(Schedulers.io());

Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        Log.d("233","emit A");
        e.onNext("A");
        Thread.sleep(1000);
        Log.d("233","emit B");
        e.onNext("B");
        Thread.sleep(1000);
        Log.d("233","emit C");
        e.onNext("C");
        Thread.sleep(1000);
        Log.d("233","emit complete2");
        e.onComplete();
    }
}).subscribeOn(Schedulers.io());
Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
    @Override
    public String apply(Integer integer, String s) throws Exception {
        return integer + s;
    }
}).subscribe(new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d("233","onSubscribe");
    }

    @Override
    public void onNext(String value) {
        Log.d("233","onNext"+value);

    }

    @Override
    public void onError(Throwable e) {
        Log.d("233","OnErron");

    }

    @Override
    public void onComplete() {
        Log.d("233","oncomplete");

    }
});

结果:
这里写图片描述

注意:
这块其实还有很多问题,下一篇博客再说

总结

就觉得Rxjava的操作符很厉害唉,继续学习了唉
参考的大佬博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
卡尔曼滤波器学习笔记) 在上一篇笔记中,我们介绍了卡尔曼滤波器的基本原理和数学模型。现在,让我们继续深入学习卡尔曼滤波器的实际应用。 1. 状态方程(State Equation): 卡尔曼滤波器的核心是状态方程,描述系统的状态如何随时间变化。通常表示为x(k+1) = A * x(k) + B * u(k) + w(k),其中x(k)表示系统在时刻k的状态,A是状态转移矩阵,u(k)表示输入,B是输入矩阵,w(k)表示过程噪声。 2. 观测方程(Measurement Equation): 观测方程描述了系统状态与观测值之间的关系。通常表示为z(k) = H * x(k) + v(k),其中z(k)表示观测值,H是观测矩阵,v(k)表示观测噪声。 3. 卡尔曼增益(Kalman Gain): 卡尔曼增益决定了如何将先验估计与观测值相结合,得到更准确的后验估计。卡尔曼增益的计算公式为K(k) = P(k|k-1) * H^T * (H * P(k|k-1) * H^T + R)^-1,其中P(k|k-1)表示先验误差协方差矩阵,R表示观测噪声的协方差矩阵。 4. 预测步骤(Prediction Step): 预测步骤用于根据系统的模型预测下一时刻的状态和误差协方差矩阵。预测步骤的计算公式为x(k+1|k) = A * x(k|k) + B * u(k),P(k+1|k) = A * P(k|k) * A^T + Q,其中x(k|k)表示先验估计,P(k|k)表示先验误差协方差矩阵,Q表示过程噪声的协方差矩阵。 5. 更新步骤(Update Step): 更新步骤用于根据观测值修正先验估计,得到后验估计和后验误差协方差矩阵。更新步骤的计算公式为x(k+1|k+1) = x(k+1|k) + K(k+1) * (z(k+1) - H * x(k+1|k)),P(k+1|k+1) = (I - K(k+1) * H) * P(k+1|k),其中x(k+1|k+1)表示后验估计,P(k+1|k+1)表示后验误差协方差矩阵,K(k+1)表示卡尔曼增益。 以上就是卡尔曼滤波器的基本概念和计算步骤。在实际应用中,我们需要根据具体问题来确定状态方程、观测方程和相关参数。卡尔曼滤波器的优势在于可以有效地处理噪声和不确定性,广泛应用于目标跟踪、导航、机器人等领域。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值