Преобразовать один <Список> в наблюдаемый ?

#java #rx-java #reactive-programming

#java #rx-java #реактивное программирование

Вопрос:

Цель

Я получаю Single<List<Item>> ответ от сетевого запроса. В конце я хотел бы использовать эти элементы либо как a Observable<Item2> , либо как a Single<List<Item2>> . Я перехожу от Item к Item2 с. new Item2(Item item)

То, что я думал, сработает

 Single<List<Item>> items
    .map(Observable::fromIterable) // Single<List> to Observable
    .map(new Function<Observable<Item>, Observable<Item2>>() {
      // I don't really know how I can do it here
    })
    .subscribeOn(//.../)
    .observeOn(//.../);
  

Я думал, что смогу преобразовать типы observables с map помощью, поэтому я не совсем понимаю, почему параметрами второго map являются Observable<Item> s, а не Item .
Как я мог добиться этого правильно?

Комментарии:

1. Я думаю, вам нужно использовать flatMap .

2. @AluanHaddad вот и все, спасибо.

Ответ №1:

Если я правильно понял, вы хотите преобразовать Single<List<Item>> в поток Item2 объектов и иметь возможность работать с ними последовательно. В этом случае вам необходимо преобразовать список в наблюдаемый, который последовательно генерирует элементы, используя .toObservable().flatMap(...) для изменения типа наблюдаемого.

Например:

 Single<List<Item>> items = Single.just(new ArrayList<>());
items.toObservable()
            .flatMap(new Func1<List<Item>, Observable<Item>>() {
                @Override
                public Observable<Item> call(List<Item> items) {
                    return Observable.from(items);
                }
            })
            .map(new Func1<Item, Item2>() {
                @Override
                public Item2 call(Item item) {
                    return new Item2(item);
                }
            })
            .subscribeOn(//.../)
            .observeOn(//.../);
  

Или, используя ссылки на методы, вы можете сделать этот код еще более простым:

 items.toObservable()
            .flatMap(Observable::from)
            .map(Item2::new)
            .subscribeOn(//.../)
            .observeOn(//.../)
            .subscribe();
  

Подводя итог: если вы хотите изменить тип Observable , используйте .flatMap()

Комментарии:

1. Спасибо! Я использовал map , когда должен был использовать flatMap .

2. Будет ли способ Rx изменить тип Item to Item2 и сохранить Single<List<T>> вывод? Итак, я бы ввел a Single<List<Item>> в качестве входных данных и вывел a Single<List<Item2>> .

3. Да, вы можете использовать .toList().toSingle() сразу после .map() (или просто .toList() , если вы не заботитесь о том, чтобы получить Single конкретно).

4. Вместо toObservalble().flatMap() того, чтобы вы могли бы использовать flatMapObservable()

5. Круто! Спасибо (: Не знал, что

Ответ №2:

Есть несколько методов для этого:

 items.flatMapObservable(Observable::fromIterable).map(Item2::new).toList()

// or

items.toObservable.flatMap(Observable::fromIterable).map(Item2::new).toList()

// or

items.toObservable().flatMapIterable(Functions.identity()).map(Item2::new).toList()

  

Первый из них самый простой.