40

I am using RxJava.

I have an Observable<T>. How do I convert it to List<T>?

Seems to be a simple operation, but I couldn't find it anywhere on the net.

Jack Ukleja
  • 13,061
  • 11
  • 72
  • 113
Khanh Nguyen
  • 11,112
  • 10
  • 52
  • 65

8 Answers8

80
List<T> myList = myObservable.toList().toBlocking().single();
starball
  • 20,030
  • 7
  • 43
  • 238
diduknow
  • 1,624
  • 2
  • 13
  • 10
25

You can use toList() or toSortedList() . For e.g.

observable.toList(myObservable)
          .subscribe({ myListOfSomething -> do something useful with the list });
giampaolo
  • 6,906
  • 5
  • 45
  • 73
sol4me
  • 15,233
  • 5
  • 34
  • 34
13

RxJava 2+:

List<T> = theObservarale
             .toList()
             .blockingGet();
Andrew
  • 36,676
  • 11
  • 141
  • 113
  • this returns only 1 size, kindly check my question here please : https://stackoverflow.com/q/49562033/3974048 – david Mar 29 '18 at 18:03
5

You can also use the collect operator:

    ArrayList list = observable.collect(ArrayList::new, ArrayList::add)
                               .toBlocking()
                               .single();

With collect, you can choose which type of Collection you prefer and perform an additional operation on the item before adding it to the list.

araknoid
  • 3,065
  • 5
  • 33
  • 35
1

You can't convert observable to list in any idiomatic way, because a list isn't really a type that fits in with Rx.

If you want to populate a list with the events from a observable stream you need to basically create a list and add the items within a Subscribe method like so (C#):

IObservable<EventType> myObservable = ...;
var list = new List<EventType>();
myObservable.Subscribe(evt => list.Add(evt));

The ToList-style operators only provide a list once the stream completes (as an IObservable<List<T>>), so that isnt useful in scenarios where you have a long-lived stream or you want to see values before the stream completes.

Jack Ukleja
  • 13,061
  • 11
  • 72
  • 113
1

This works.

public static void main(String[] args) {

    Observable.just("this", "is", "how", "you", "do", "it")
            .lift(customToList())
            .subscribe(strings -> System.out.println(String.join(" ", strings)));

}

public static <T> ObservableOperator<List<T>, T> customToList() {

    return observer -> new DisposableObserver<T>() {

        ArrayList<T> arrayList = new ArrayList<>();
        @Override
        public void onNext(T t) {
            arrayList.add(t);
        }

        @Override
        public void onError(Throwable throwable) {
            observer.onError(throwable);
        }

        @Override
        public void onComplete() {
            observer.onNext(arrayList);
            observer.onComplete();
        }
    };
}`
0

This might be a late answer, hope it helps somebody in future.

There is an operator collectInto(). I would suggest everyone to not use blocking() (unless in a test case) as you completely loose the purpose of async events in Rxchains. Try to chain your operations as much as possible

Completable setList(List<Integer> newIntegerList, Observable<Integer> observable){
   return observable.collectInto(newIntegerList, List::add).ignoreElement();
}

 // Can call this method
 Observable<Integer> observable = Observable.just(1, 2, 3);
 List<Integer> list = new ArrayList<>();
 setList(list, observable);

You save the hassle of using blocking() in this case.

Anonymous
  • 2,184
  • 15
  • 23
-12

Found it myself

public static <T> List<T> toList(Observable<T> observable) {
    final List<T> list = new ArrayList<T>();

    observable.toBlocking().forEach(new Action1<T>() {
        @Override
        public void call(T t) {
            list.add(t);
        }
    });

    return list;
}
Khanh Nguyen
  • 11,112
  • 10
  • 52
  • 65
  • 4
    This is a bit of an anti-pattern. Use `Observable.toList()` instead, and make sure that the `Observable` is not infinite or you will have problems. – tmn Aug 30 '15 at 15:21
  • As Thomas sayed, you may want to reconsider accepting this one, that's not the way to do it. – tokland Nov 06 '15 at 10:24