RxJava:如何将对象列表转换为另一个对象的列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35734060/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RxJava: How to convert List of objects to List of another objects
提问by Yura Buyaroff
I have the List of SourceObjects and I need to convert it to the List of ResultObjects.
我有 SourceObjects 列表,我需要将它转换为 ResultObjects 列表。
I can fetch one object to another using method of ResultObject:
我可以使用 ResultObject 的方法将一个对象提取到另一个对象:
convertFromSource(srcObj);
of course I can do it like this:
我当然可以这样做:
public void onNext(List<SourceObject> srcObjects) {
List<ResultsObject> resObjects = new ArrayList<>();
for (SourceObject srcObj : srcObjects) {
resObjects.add(new ResultsObject().convertFromSource(srcObj));
}
}
but I will be very appreciate to someone who can show how to do the same using rxJava.
但我将非常感谢可以展示如何使用rxJava执行相同操作的人。
采纳答案by dwursteisen
If your Observable
emits a List
, you can use these operators:
如果您Observable
发出 a List
,则可以使用以下运算符:
flatMapIterable
(transform your list to an Observable of items)map
(transform your item to another item)toList
operators (transform a completed Observable to a Observable which emit a list of items from the completed Observable)Observable<SourceObjet> source = ... source.flatMapIterable(list -> list) .map(item -> new ResultsObject().convertFromSource(item)) .toList() .subscribe(transformedList -> ...);
flatMapIterable
(将您的列表转换为 Observable 的项目)map
(将您的项目转换为另一个项目)toList
运算符(将完整的 Observable 转换为 Observable,从完整的 Observable 发出项目列表)Observable<SourceObjet> source = ... source.flatMapIterable(list -> list) .map(item -> new ResultsObject().convertFromSource(item)) .toList() .subscribe(transformedList -> ...);
回答by lujop
You can use mapoperator. For example if you have listsof integers and you want to convert to listsof doubles:
您可以使用地图运算符。例如,如果你有名单小号整数,你要转换列表小号双打:
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;
});
But all it's a lot more natural if you can control the observable and change it to observe single elements instead of collections. Same code that converts single integer elements into double ones:
但是,如果您可以控制 observable 并将其更改为观察单个元素而不是集合,那就更自然了。将单个整数元素转换为双整数元素的相同代码:
Observable.just(1,2,3).map( elem -> elem.doubleValue())
回答by murki
The Observable.from()factory method allows you to convert a collection of objects into an Observable stream. Once you have a stream you can use the mapoperator to transform each emitted item. Finally, you will have to subscribe to the resulting Observable in order to use the transformed items:
该Observable.from()工厂方法允许你对象的集合转换成可观察到的数据流。一旦你有了一个流,你就可以使用map操作符来转换每个发出的项目。最后,您必须订阅生成的 Observable 才能使用转换后的项目:
// 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
}
});
The abbreviated version if you use lambdas would look like this:
如果您使用 lambda,则缩写版本如下所示:
Observable.from(srcObjects)
.map(srcObj -> new ResultsObject().convertFromSource(srcObj))
.subscribe(resultsObject -> ...);
回答by AtanL
Don't break the chain, just like this.
不要打破链条,就像这样。
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.
});
回答by Noel
If you want to maintain the Lists
emitted by the source Observable
but convert the contents, i.e. Observable<List<SourceObject>>
to Observable<List<ResultsObject>>
, you can do something like this:
如果您想维护Lists
源发出Observable
的内容但转换内容,即Observable<List<SourceObject>>
to Observable<List<ResultsObject>>
,您可以执行以下操作:
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 -> ...);
This ensures a couple of things:
这确保了几件事:
- The number of
Lists
emitted by theObservable
is maintained. i.e. if the source emits 3 lists, there will be 3 transformed lists on the other end - Using
Observable.fromIterable()
will ensure the innerObservable
terminates so thattoList()
can be used
- 由
Lists
发出的数量Observable
保持不变。即如果源发出 3 个列表,则另一端将有 3 个转换后的列表 - 使用
Observable.fromIterable()
将确保内部Observable
终止以便toList()
可以使用
回答by saiday
If what you need is simply List<A>
to List<B>
without manipulating result of List<B>
.
如果你需要的是简单List<A>
到List<B>
没有操纵的结果List<B>
。
The cleanest version is:
最干净的版本是:
List<A> a = ... // ["1", "2", ..]
List<B> b = Observable.from(a)
.map(a -> new B(a))
.toList()
.toBlocking()
.single();
回答by Andrew
As an extension to Noelgreat answer. Let's say transformation also depends on some server data that might change during subscription. In that case use flatMap+ scan.
作为Noel的扩展很好的答案。假设转换还取决于订阅期间可能会更改的某些服务器数据。在这种情况下,请使用flatMap+ scan。
As a result when id list changes, transformations will restart anew. And when server data changes related to a specific id, single item will be retransformed as well.
因此,当 id 列表更改时,转换将重新开始。当与特定 id 相关的服务器数据发生变化时,单个项目也将被重新转换。
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)
}
}
}
回答by tomrozb
Non blocking conversion using nested map function
使用嵌套映射函数的非阻塞转换
val ints: Observable<List<Int>> = Observable.fromArray(listOf(1, 2, 3))
val strings: Observable<List<String>> = ints.map { list -> list.map { it.toString() } }
回答by Usman Zafer
Using toList() waits for the source observable to complete, so if you do that on an infinite observable (like one bound to UI events and Database calls), you will never get anything in your subscribe().
使用 toList() 等待源 observable 完成,所以如果你在无限的 observable 上这样做(比如绑定到 UI 事件和数据库调用),你将永远不会在你的 subscribe() 中得到任何东西。
The solution to that is to Use FlatMapSingleor SwitchMapSingle.
解决方案是使用FlatMapSingle或SwitchMapSingle。
Observable<List<Note>> observable = noteDao.getAllNotes().flatMapSingle(list -> Observable.fromIterable(list).toList());
Now,everytime your list is updated, you can make that event behave as an observable.
现在,每次更新您的列表时,您都可以使该事件表现为可观察的。