RxJava: How to convert List of objects to List of another objects
I have the List of SourceObjects and I need to convert it to the List of ResultObjects.
I can fetch one object to another using method of ResultObject:
convertFromSource(srcObj);
of course I can do it like this:
public void onNext(List<SourceObject> srcObjects) {
List<ResultsObject> resObjects = new ArrayList<>();
for (SourceObject srcObj : srcObjects) {
resObjects.add(new ResultsObject().convertFromSource(srcObj));
}
}
but I will be very appreciate to someone who can show how to do the same using rxJava.
Solution 1:
If your Observable
emits a List
, you can use these operators:
-
flatMapIterable
(transform your list to an Observable of items) -
map
(transform your item to another item) -
toList
operators (transform a completed Observable to a Observable which emit a list of items from the completed Observable)Observable<SourceObjet> source = ... source.flatMapIterable(list -> list) .map(item -> new ResultsObject().convertFromSource(item)) .toList() .subscribe(transformedList -> ...);
Solution 2:
If you want to maintain the Lists
emitted by the source Observable
but convert the contents, i.e. Observable<List<SourceObject>>
to Observable<List<ResultsObject>>
, you can do something like this:
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 -> ...);
This ensures a couple of things:
- The number of
Lists
emitted by theObservable
is maintained. i.e. if the source emits 3 lists, there will be 3 transformed lists on the other end - Using
Observable.fromIterable()
will ensure the innerObservable
terminates so thattoList()
can be used
Solution 3:
The Observable.from() factory method allows you to convert a collection of objects into an Observable stream. Once you have a stream you can use the map operator to transform each emitted item. Finally, you will have to subscribe to the resulting Observable in order to use the transformed items:
// 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
}
});
The abbreviated version if you use lambdas would look like this:
Observable.from(srcObjects)
.map(srcObj -> new ResultsObject().convertFromSource(srcObj))
.subscribe(resultsObject -> ...);