RxJava:如何将对象列表转换为另一个对象的List

Yur*_*off 54 java android rx-java

我有SourceObjects列表,我需要将它转换为ResultObjects列表.

我可以使用ResultObject的方法将一个对象提取到另一个对象:

convertFromSource(srcObj);
Run Code Online (Sandbox Code Playgroud)

当然我可以这样做:

public void onNext(List<SourceObject> srcObjects) {
   List<ResultsObject> resObjects = new ArrayList<>();
   for (SourceObject srcObj : srcObjects) {
       resObjects.add(new ResultsObject().convertFromSource(srcObj));
   }
}
Run Code Online (Sandbox Code Playgroud)

但我会非常感谢能够使用rxJava展示如何做同样事情的人.

dwu*_*sen 69

如果您Observable发出a List,则可以使用以下运算符:

  • flatMapIterable (将您的列表转换为Observable项目)
  • map (将您的项目转换为另一个项目)
  • toList 运算符(将已完成的Observable转换为Observable,该Observable从已完成的Observable中发出项目列表)

    Observable<SourceObjet> source = ...
    source.flatMapIterable(list -> list)
          .map(item -> new ResultsObject().convertFromSource(item))
          .toList()
          .subscribe(transformedList -> ...);
    
    Run Code Online (Sandbox Code Playgroud)

  • 这看起来很干净,但有一些缺点.1.如果source发出多个列表,那么它们将被"flatMapIterable"压缩为单个对象流,而`toList()`将它们收集在一个列表中.因此,如果您关心多个排放并将它们保存在单独的列表中,那么很遗憾您会失去这一点.2.`toList()`等待源observable完成,所以如果你在一个无限的可观察对象(比如一个绑定到UI事件)上那样做,你将永远不会在你的`subscribe()`中得到任何东西. (21认同)
  • 我想你只需要使用不同的方法.如果你试图转换列表的每个元素,你可能只需要`.map(list - >/*使用plain old for loop*/构建一个新列表)`.或者使用任何其他方法来转换`.map()`中的列表.否则你可以在你的无限可观测量上使用像`.take(itemCount)`这样的运算符来使它变得有限.请注意,这显然会丢弃`itemCount`之后的所有元素,因此可能不是您想要的. (5认同)

Noe*_*oel 58

如果你想保持Lists由源发射Observable,但转换的内容,即Observable<List<SourceObject>>Observable<List<ResultsObject>>,你可以这样做:

Observable<List<SourceObject>> source = ...
source.flatMap(list ->
        Observable.fromIterable(list)
            .map(item -> new ResultsObject().convertFromSource(item))
            .toList()
            .toObservable() // Required for RxJava 2.x
    )
    .subscribe(resultsList -> ...);
Run Code Online (Sandbox Code Playgroud)

这确保了以下几点:

  • 保持Lists发射的数量Observable.即如果源发出3个列表,则另一端将有3个变换列表
  • 使用Observable.fromIterable()将确保内部Observable终止以便toList()可以使用


mur*_*rki 10

Observable.from()工厂方法允许你对象的集合转换成可观察到的数据流.获得流后,您可以使用map运算符转换每个发出的项.最后,您必须订阅生成的Observable才能使用转换后的项目:

// Assuming List<SourceObject> srcObjects
Observable<ResultsObject> resultsObjectObservable = Observable.from(srcObjects).map(new Func1<SourceObject, ResultsObject>() {
    @Override
    public ResultsObject call(SourceObject srcObj) {
        return new ResultsObject().convertFromSource(srcObj);
    }
});

resultsObjectObservable.subscribe(new Action1<ResultsObject>() { // at this point is where the transformation will start
    @Override
    public void call(ResultsObject resultsObject) { // this method will be called after each item has been transformed
        // use each transformed item
    }
});
Run Code Online (Sandbox Code Playgroud)

如果你使用lambdas的缩写版本将如下所示:

Observable.from(srcObjects)
  .map(srcObj -> new ResultsObject().convertFromSource(srcObj))
  .subscribe(resultsObject -> ...);
Run Code Online (Sandbox Code Playgroud)


Ata*_*anL 5

不要打破链条,就像这样。

Observable.from(Arrays.asList(new String[] {"1", "2", "3", }))
.map(s -> Integer.valueOf(s))
.reduce(new ArrayList<Integer>, (list, s) -> {
    list.add(s);
    return list;
})
.subscribe(i -> {
    // Do some thing with 'i', it's a list of Integer.
});
Run Code Online (Sandbox Code Playgroud)