将可观察对象转换为列表。

41

我正在使用RxJava。

我有一个Observable<T>,如何将其转换为List<T>

看起来这是一个简单的操作,但我在网上找不到任何相关信息。

8个回答

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

6
这将导致阻塞,而不是异步。 - Zulqurnain Jutt
5
@ZulqurnainJutt - toBlocking 呼叫是一个提示吗?(问题并未要求它是异步的) - Nick Cardoso

25

您可以使用toList()toSortedList()。例如:

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

10
这并不会将其转换为列表。这基本上与我调用subscribe一样。 - Adam Arold
7
请注意,toList() 方法只有在序列结束时才会创建列表,因此对于长时间运行的流不太有用。 - Jack Ukleja

13

RxJava 2+:

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

这只返回了一个大小,请查看我的问题:https://stackoverflow.com/q/49562033/3974048 - david

5
您也可以使用collect运算符:
    ArrayList list = observable.collect(ArrayList::new, ArrayList::add)
                               .toBlocking()
                               .single();

使用collect,您可以选择首选的Collection类型,并在将项目添加到列表之前执行附加操作。

3
使用方法引用,可以将collect写成collect(ArrayList::new, ArrayList::add) - Will
感谢您的建议,我在这里错过了方法引用的使用。 - araknoid

1

任何常规的方式都无法将可观测对象转换为列表,因为列表并不是适合Rx的类型。

如果您想使用可观测流中的事件填充列表,您需要基本上创建一个列表,并在Subscribe方法中添加项目,如下所示(C#):

IObservable<EventType> myObservable = ...;
var list = new List<EventType>();
myObservable.Subscribe(evt => list.Add(evt));
< p > ToList 样式的运算符仅在流完成时提供列表(作为 IObservable<List<T>>),因此在您拥有长时间存活的流或者您希望在流完成之前查看值的情况下是无用的。


1
这是有效的。
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

这可能是一个晚回答,但希望能帮助到未来的某个人。

有一个操作符collectInto()。我建议大家不要使用blocking()(除非在测试用例中),因为你会完全失去Rxchains异步事件的目的。尽可能地链接您的操作。

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

你可以省去在这种情况下使用 blocking() 的麻烦。

-11

我自己找到了

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

4
这有点反模式。请改用Observable.toList(),确保Observable不是无限的,否则会出现问题。 - tmn
正如Thomas所说,您可能需要重新考虑接受这个,那不是做这件事的方法。 - tokland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接