You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxJava2:如何为多个Rx链复用指定操作符序列?

Reusing RxJava Operator Sequences: Extracting flatMapIterable, sorted, and toList()

Great question! Reusing common operator sequences in RxJava is a fantastic way to keep your code DRY (Don’t Repeat Yourself) and easier to maintain. Here’s a clean, scalable approach to package that sequence for reuse across multiple Rx chains:

Step 1: Create a Reusable ObservableTransformer

We’ll wrap your target operators in a generic ObservableTransformer—RxJava’s built-in tool for packaging reusable operator logic. This transformer will take an Observable<List<T>>, process it through your desired steps, and return an Observable<List<T>> (adjust the generic type T to match your actual model class):

import io.reactivex.Observable;
import io.reactivex.ObservableTransformer;
import java.util.Comparator;
import java.util.List;

public class RxUtils {
    // Generic transformer to flatten, sort, and convert back to a List
    public static <T> ObservableTransformer<List<T>, List<T>> flattenSortAndToList(Comparator<T> comparator) {
        return upstream -> upstream
            .flatMapIterable(items -> items) // Flatten the List into individual items
            .sorted(comparator) // Sort items using the provided comparator
            .toList() // Collect sorted items back into a List
            .toObservable(); // Convert Single<List<T>> back to Observable<List<T>>
    }
}

Step 2: Apply the Transformer in Your Rx Chain

Replace the duplicated operators with the compose() method to inject your reusable sequence. This keeps your original chain concise and consistent:

compositeDisposable.add(manager.getObservable()
    .map(objects -> modelMapper.map(objects))
    .map(modelObjects -> { 
        cache.save(modelObjects); 
        return modelObjects; 
    })
    .compose(RxUtils.flattenSortAndToList(objectComparator)) // Reuse the operator sequence here
    .map(modelObjects -> viewModelMapper.map(modelObjects))
    .subscribe(this::onObjectsLoaded));

Key Benefits of This Approach

  • Efficiency: Using compose() applies the transformer directly to the upstream Observable, avoiding the overhead of nested Observables (unlike flatMap()).
  • Flexibility: The generic <T> type lets you reuse this transformer with any model class, as long as you provide a matching Comparator<T>.
  • Maintainability: If you ever need to adjust the sequence (e.g., add a filter, tweak sorting logic), you only update it once in the transformer instead of every Rx chain.

Alternative: For Single Chains

If your upstream source returns a Single instead of an Observable, you can create a SingleTransformer variant:

import io.reactivex.Single;
import io.reactivex.SingleTransformer;
import java.util.Comparator;
import java.util.List;

public class RxUtils {
    public static <T> SingleTransformer<List<T>, List<T>> flattenSortAndToListSingle(Comparator<T> comparator) {
        return upstream -> upstream
            .flatMapObservable(Observable::fromIterable)
            .sorted(comparator)
            .toList();
    }
}

Use it with a Single chain like this:

compositeDisposable.add(manager.getSingle() // Assuming manager returns Single<List<...>>
    .map(objects -> modelMapper.map(objects))
    .map(modelObjects -> { 
        cache.save(modelObjects); 
        return modelObjects; 
    })
    .compose(RxUtils.flattenSortAndToListSingle(objectComparator))
    .map(modelObjects -> viewModelMapper.map(modelObjects))
    .subscribe(this::onObjectsLoaded));

内容的提问来源于stack exchange,提问作者Marius Andrei Rosu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:25:42