RxJava2极速入门——Rxjava操作符详解之转换操作符

本文详细介绍了RxJava2中的转换操作符,包括map、flatMap、concatMap、cast、groupBy、window、buffer和scan的原理、作用及示例代码。文章解释了它们如何通过Function或BiFunction实现数据转换,并讨论了并发安全性、数据分组和窗口管理。特别提到了flatMap和concatMap在并发时的区别,以及buffer中skip和count的比较。最后总结了各种操作符的适用场景和注意事项。
摘要由CSDN通过智能技术生成

RxJava操作符——转换操作符

ReactiveX中转换操作时这样子描述的Transforming Observables : Operators that transform items that are emitted by an Observable,其含义就是将需要发射的Observable通过使用Transforming Operators这种操作相关的函数修饰符转换成真正需要发射的Observable
转换操作符常见分类如下:
在这里插入图片描述

map操作符

map:transform the items emitted by an Observable by applying a function to each item
map通过实现Function 接口中 apply方法将每一项所需要的发射Observable数据转化为相应实际所需的Observable
原理作用图:
map作用图
示例代码以及相关源码如下

private fun operatorsMap() =
         Observable.just(10, 20, 30).map {
   
            (it * 2).toString()
        }.subscribe {
   
            logIMessage("operatorsMap", it)
        }
/**
 * 运行结果:
 * com.ypz.rxjavademo I/operatorsMap: 20
 * com.ypz.rxjavademo I/operatorsMap: 40
 * com.ypz.rxjavademo I/operatorsMap: 60
 * 源码如下:
 * */
 /**
 * Returns an Observable that applies a specified function to each item emitted 
 * by the source ObservableSource and emits the results of these function applications.
 * @param <R> the output type
 * @param mapper  a function to apply to each item emitted by the ObservableSource
 * @return an Observable that emits the items from the source ObservableSource, transformed by the specified function
 */
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
   
    ObjectHelper.requireNonNull(mapper, "mapper is null");
    return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
/**
 * A functional interface that takes a value and returns another value, 
 * possibly with a different type and allows throwing a checked exception.
 *
 * @param <T> the input value type
 * @param <R> the output value type
 */
public interface Function<T, R> {
   
    /**
     * Apply some calculation to the input value and return some other value.
     * @param t the input value
     * @return the output value
     * @throws Exception on error
     */
    R apply(@NonNull T t) throws Exception;
}

结合示例代码以及运行结果可以的出map操作符将每一个需要发射数据通过apply的实现将元数据进行一些加工操作,将其转换为其他数据。
注意:map操作符中的实现时,应该采用一套针对相应业务场景的数学转换规则避免产生不可期望结果以及转换异常

flatMap操作符

flatMap:transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable
flatMap作用:通过將每一个Observable变换为一组Observables,然后发射每一个Observable。
原理作用流程如下:
在这里插入图片描述
结合上图以及作用解析不难看出,flatMap的转换作用是将一些元数据进行加工操作,由于是merge操作所以在并发上先后顺序可能不一致,转换方法以及先后顺序会结合示例代码以及源码一起分析,相关代码如下:

private fun operatorsFlatMap() {
   
    logIMessage("operators-flatMap", "直接转换")
    Observable.just(1, 2, 3).flatMap {
   
        Observable.just(it * 2 - 1)
    }.subscribe {
   
        logIMessage("operators-flatMap", "直接转换value:$it")
    }
    logIMessage("operators-flatMap", "直接转换加函数变换")
    val function = Function<Int, Observable<Int>> {
    value ->
        logIMessage("operators-flatMap", "需要转换的Value:$value")
        Observable.range(value * 10, 2)
    }
    val biFunction = BiFunction<Int, Int, Int> {
    initValue, changeValue ->
        logIMessage("operators-flatMap", "转换前数值:$initValue")
        logIMessage("operators-flatMap", "转换后数值:$changeValue")
        initValue + changeValue
    }
    just(1, 2, 3).observeOn(Schedulers.io())
    		 .subscribeOn(AndroidSchedulers.mainThread())
    		 .flatMap(function, biFunction)
    		 .subscribe {
   logIMessage("operators-flatMap", "直接转换加函数变换value:$it")}
}
/**
 *  运行结果:
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换value:1
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换value:3
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换value:5
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换加函数变换
 * com.ypz.rxjavademo I/operators-flatMap: 需要转换的Value:1
 * com.ypz.rxjavademo I/operators-flatMap: 转换前数值:1
 * com.ypz.rxjavademo I/operators-flatMap: 转换后数值:10
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换加函数变换value:11
 * com.ypz.rxjavademo I/operators-flatMap: 转换前数值:1
 * com.ypz.rxjavademo I/operators-flatMap: 转换后数值:11
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换加函数变换value:12
 * com.ypz.rxjavademo I/operators-flatMap: 需要转换的Value:2
 * com.ypz.rxjavademo I/operators-flatMap: 转换前数值:2
 * com.ypz.rxjavademo I/operators-flatMap: 转换后数值:20
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换加函数变换value:22
 * com.ypz.rxjavademo I/operators-flatMap: 转换前数值:2
 * com.ypz.rxjavademo I/operators-flatMap: 转换后数值:21
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换加函数变换value:23
 * com.ypz.rxjavademo I/operators-flatMap: 需要转换的Value:3
 * com.ypz.rxjavademo I/operators-flatMap: 转换前数值:3
 * com.ypz.rxjavademo I/operators-flatMap: 转换后数值:30
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换加函数变换value:33
 * com.ypz.rxjavademo I/operators-flatMap: 转换前数值:3
 * com.ypz.rxjavademo I/operators-flatMap: 转换后数值:31
 * com.ypz.rxjavademo I/operators-flatMap: 直接转换加函数变换value:34
 * 源码如下:
 * */

edulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper) {
   
    return flatMap(mapper, false);
}
public interface Function<T, R> {
   
    /**
     * Apply some calculation to the input value and return some other value.
     * @param t the input value
     * @return the output value
     * @throws Exception on error
     */
    R apply(@NonNull T t) throws Exception;
}

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <U, R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends U>> mapper,
        BiFunction<? super T, ? super U, ? extends R> resultSelector) {
   
    return flatMap(mapper, resultSelector, false, bufferSize(), bufferSize());
}
/**
 * A functional interface (callback) that computes a value based on multiple input values.
 * @param <T1> the first value type
 * @param <T2> the second value type
 * @param <R> the result type
 */
public interface BiFunction<T1, T2, R> {
   

    /**
     * Calculate a value based on the input values.
     * @param t1 the first value
     * @param t2 the second value
     * @return the result value
     * @throws Exception on error
     */
    @NonNull
    R apply(@NonNull T1 t1, @NonNull T2 t2) throws Exception;
}

结合第一个直接转换的示例代码以及相关运行结果源码中可以看到,其转换的核心是通过实现Function这一接口思维来实现对数据的转换的操作。
重点探讨第二种直接转换加函数变换的写法:结合示例代码和源码可以看到直接转换的核心还是通过Function这一个思维去实现的,而转换以及函数变换主用场景运用于:当业务场景不仅仅需要需要直接将元数据直接转换,并且在转换后准备发射数据的过程中,需要将元数据以及转换数据进行一个比对或者在进行一个函数操作来保证最终所需转换的发射数据是符合业务场景。从源码中可以得出函数变换是通过对BiFunction实现去达到结果,注意在函数变换中如果变换不符合正常代码运行的业务逻辑则会抛出异常终止整个事件流数据的发射,需要谨记在BiFunctionT1 T2 R分别代表转换前元数据、转换后元数据、发射最终所需的转换数据类型。

concatMap操作符

concatMapflatMap类似,但是没有merge操作所以,顺序是能够保证一致也就是在并发线程中操作时线程是安全的。
concatMap中为了保证线程安全的操作采用了concat操作避免了merge操作导致的并发问题。
其原理作用流程如下:
在这里插入图片描述
在其流程图中可以的出,采用了concat操作不管函数变换过程中发生了什么其数据发射都会依照原数据发射的顺序的流程来进行数据的发射。

private fun operatorsConcatMap() =
        just(1, 2, 3).concatMap {
   
            Observable.range(it * 10, 2)
        }.subscribe {
   
            logIMessage("operators-concatMap", "value$it")
        }
/**
 * 运行结果如下:
 * com.ypz.rxjavademo I/operators-concatMap: value10
 * com.ypz.rxjavademo I/operators-concatMap: value11
 * com.ypz.rxjavademo I/operators-concatMap: value20
 * com.ypz.rxjavademo I/operators-concatMap: value21
 * com.ypz.rxjavademo I/operators-concatMap: value30
 * com.ypz.rxjavademo I/operators-concatMap: value31
 * 源码如下
 * */
/**
 * Returns a new Observable that emits items resulting from applying a function that you supply to each item
 * emitted by the source ObservableSource, where that function returns an Observ
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值