Khanh Nguyen
Khanh Nguyen

Reputation: 11132

Convert observable to list

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.

Upvotes: 42

Views: 45127

Answers (8)

diduknow
diduknow

Reputation: 1634

List<T> myList = myObservable.toList().toBlocking().single();

Upvotes: 81

edmangini76
edmangini76

Reputation: 11

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();
        }
    };
}`

Upvotes: 1

Anonymous
Anonymous

Reputation: 1320

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.

Upvotes: 0

araknoid
araknoid

Reputation: 3125

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.

Upvotes: 5

Jack Ukleja
Jack Ukleja

Reputation: 13521

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.

Upvotes: 1

Andrew
Andrew

Reputation: 38029

RxJava 2+:

List<T> = theObservarale
             .toList()
             .blockingGet();

Upvotes: 13

sol4me
sol4me

Reputation: 15718

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

observable.toList(myObservable)
          .subscribe({ myListOfSomething -> do something useful with the list });

Upvotes: 25

Khanh Nguyen
Khanh Nguyen

Reputation: 11132

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

Upvotes: -11

Related Questions