tutorial rxjava2 rxjava rxandroid que example español java android rx-java

rxjava2 - rxjava tutorial



RxJava: Cómo convertir la Lista de objetos a la Lista de otros objetos (8)

Tengo la Lista de SourceObjects y necesito convertirla a la Lista de ResultObjects.

Puedo buscar un objeto a otro usando el método de ResultObject:

convertFromSource(srcObj);

por supuesto que puedo hacerlo así:

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

pero agradeceré mucho a alguien que pueda mostrar cómo hacer lo mismo usando rxJava .


Como una extensión a Noel gran respuesta. Digamos que la transformación también depende de algunos datos del servidor que pueden cambiar durante la suscripción. En ese caso, use flatMap + scan .

Como resultado, cuando la lista de identificación cambia, las transformaciones se reiniciarán nuevamente. Y cuando los datos del servidor cambien en relación con una identificación específica, también se volverá a transformar un solo elemento.

fun getFarmsWithGroves(): Observable<List<FarmWithGroves>> { return subscribeForIds() //may change during subscription .switchMap { idList: Set<String> -> Observable.fromIterable(idList) .flatMap { id: String -> transformId(id) } //may change during subscription .scan(emptyList<FarmWithGroves>()) { collector: List<FarmWithGroves>, candidate: FarmWithGroves -> updateList(collector, candidate) } } }


Conversión sin bloqueo mediante la función de mapa anidado

val ints: Observable<List<Int>> = Observable.fromArray(listOf(1, 2, 3)) val strings: Observable<List<String>> = ints.map { list -> list.map { it.toString() } }


El método de fábrica Observable.from() permite convertir una colección de objetos en una secuencia Observable. Una vez que tenga una secuencia, puede usar el operador de map para transformar cada elemento emitido. Finalmente, deberá suscribirse al Observable resultante para usar los elementos transformados:

// 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 } });

La versión abreviada si usa lambdas se vería así:

Observable.from(srcObjects) .map(srcObj -> new ResultsObject().convertFromSource(srcObj)) .subscribe(resultsObject -> ...);


No rompas la cadena, así.

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. });


Puedes usar el operador de map . Por ejemplo, si tiene una lista de enteros y desea convertir a una lista de dobles:

List<Integer> li = new ArrayList<>(); Observable.just(li).map( l -> { List<Double> lr = new ArrayList<Double>(); for(Integer e:l) { lr.add(e.doubleValue()); } return lr; });

Pero todo es mucho más natural si puede controlar lo observable y cambiarlo para observar elementos individuales en lugar de colecciones. El mismo código que convierte elementos enteros simples en elementos dobles:

Observable.just(1,2,3).map( elem -> elem.doubleValue())


Si desea mantener las Lists emitidas por la fuente Observable pero convertir los contenidos, es decir, Observable<List<SourceObject>> a Observable<List<ResultsObject>> , puede hacer algo como esto:

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 -> ...);

Esto asegura un par de cosas:

  • Se mantiene el número de Lists emitidas por el Observable . es decir, si la fuente emite 3 listas, habrá 3 listas transformadas en el otro extremo
  • El uso de Observable.fromIterable() garantizará que el Observable interno termine de modo que se pueda usar toList()

Si lo que necesita es simplemente List<A> a List<B> sin manipular el resultado de List<B> .

La versión más limpia es:

List<A> a = ... // ["1", "2", ..] List<B> b = Observable.from(a) .map(a -> new B(a)) .toList() .toBlocking() .single();


Si su Observable emite una List , puede usar estos operadores:

  • flatMapIterable (transforma tu lista en un observable de elementos)
  • map (transforma tu artículo en otro artículo)
  • Operadores toList (transforman un Observable completado en un Observable que emite una lista de elementos del Observable completado)

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