带有comparator类的android rxjava排序列表
我开始在我的android项目中使用rxjava。我需要对api调用返回的事件列表进行排序。我编写了comparator类来排序列表:带有comparator类的android rxjava排序列表,android,sorting,collections,rx-java,rx-android,Android,Sorting,Collections,Rx Java,Rx Android,我开始在我的android项目中使用rxjava。我需要对api调用返回的事件列表进行排序。我编写了comparator类来排序列表: public class EventParticipantComparator { public static class StatusComparator implements Comparator<EventParticipant> { @Override public int compare(Even
public class EventParticipantComparator {
public static class StatusComparator implements Comparator<EventParticipant> {
@Override
public int compare(EventParticipant participant1, EventParticipant participant2) {
return participant1.getStatus() - participant2.getStatus();
}
}
}
我怎样才能以被动的方式实现这种情况另外,如果有任何方法可以对列表进行异步排序,我更喜欢这种方式。
无排序列表的反应方式:
dataManager.getEventImplementer().getParticipants(event.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<EventParticipant>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<EventParticipant> eventParticipants) {
}
});
dataManager.getEventImplementer().getParticipants(event.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(新订户(){
@凌驾
未完成的公共无效(){
}
@凌驾
公共无效申报人(可丢弃的e){
}
@凌驾
public void onNext(列出事件参与者){
}
});
如果我没有阅读Javadoc for,我会建议使用类似(list->Collections.sort(list,comparator))
的方法将其转换为排序数组;这里,map
是可观察的映射器
但是,上面的sort
方法是一种就地排序算法,它会影响底层数组,而不是返回完全排序的数组。因此,你应该这样做:
dataManager.getEventImplementer().getParticipants(event.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(unsortedList -> {
List<EventParticipant> sortedList = new ArrayList<>(unsortedList);
Collections.sort(sortedList, new EventParticipantComparator.StatusComparator());
return sortedList;
})
.subscribe(new Subscriber<List<EventParticipant>>() {
// ... etc.
});
dataManager.getEventImplementer().getParticipants(event.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(未分类列表->{
List sortedList=新数组列表(未排序列表);
Collections.sort(sortedList,new EventParticipantComparator.StatusComparator());
返回分类列表;
})
.subscribe(新订户(){
//……等等。
});
这将对每个传入的
列表进行单独和异步排序。此解决方案类似于公认的答案,但使用Rx运算符1)将数组拆分为对象2)按实例排序3)在专用计算线程上执行
dataManager.getEventImplementer().getParticipants(event.getId())
.flatMap(Observable::from)
.toSortedList()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(sortedList -> {...}, error -> {...});
请注意,最好使用Schedulers.io进行网络/磁盘写入,Schedulers.computation进行排序等计算我假设getParticipants()
方法返回可观察的
在下面的代码片段中,我首先使用flatMap()
操作符将Observable
转换为Observable
。此可观察对象将每次发射一个EventParticipant
。现在,通过使用toSortedList()
操作符,我可以同时对两个EventParticipant
对象执行操作,就像Comparator::compareTo
所期望的那样
在其他解决方案中,排序运算符应用于.observeOn(AndroidSchedulers.mainThread())
之后,这意味着实际的排序发生在UI线程上
getParticipants().flatMap(new Func1<List<EventParticipant>, Observable<EventParticipant>>() {
@Override
public Observable<EventParticipant> call(List<EventParticipant> eventParticipants) {
return Observable.from(eventParticipants);
}
}).subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.toSortedList(new Func2<EventParticipant, EventParticipant, Integer>() {
@Override
public Integer call(EventParticipant eventParticipant, EventParticipant eventParticipant2) {
return new StatusComparator().compare(eventParticipant, eventParticipant2);
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<EventParticipant>>() {
@Override
public void call(List<EventParticipant> eventParticipants) {
// Your sorted list on UI thread.
}
});
我修改了它,让API调用在IO调度程序上执行,在计算调度程序上排序,最后在UI线程上排序列表
getParticipants().flatMap(new Func1<List<EventParticipant>, Observable<EventParticipant>>() {
@Override
public Observable<EventParticipant> call(List<EventParticipant> eventParticipants) {
return Observable.from(eventParticipants);
}
}).subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.toSortedList(new Func2<EventParticipant, EventParticipant, Integer>() {
@Override
public Integer call(EventParticipant eventParticipant, EventParticipant eventParticipant2) {
return new StatusComparator().compare(eventParticipant, eventParticipant2);
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<EventParticipant>>() {
@Override
public void call(List<EventParticipant> eventParticipants) {
// Your sorted list on UI thread.
}
});
getParticipants().flatMap(新函数1(){
@凌驾
公共可观察呼叫(列出事件参与者){
从(事件参与者)可观察到的回报;
}
}).subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.toSortedList(新函数2(){
@凌驾
公共整数调用(EventParticipant、eventParticipant2){
返回新的StatusComparator().compare(eventParticipant,eventParticipant2);
}
}).observeOn(AndroidSchedulers.mainThread())
.订阅(新操作1(){
@凌驾
公开作废调用(列出事件参与者){
//用户界面线程上的排序列表。
}
});
还有一种方法可以对列表进行排序
dataManager.getEventImplementer().getParticipants(event.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMapIterable(participants -> participants)
.toSortedList((p1,p2) -> {p1.getStatus() - p2.getStatus()})
.subscribe(new Subscriber<List<EventParticipant>>() {
// ... etc.
});
dataManager.getEventImplementer().getParticipants(event.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMapIterable(参与者->参与者)
.toSortedList((p1,p2)->{p1.getStatus()-p2.getStatus()})
.subscribe(新订户(){
//……等等。
});
Kotlin版本:
disposable.add(interactior.getItemList()//它返回可观察的
.compose(threadTransformer.applySchedulers())
.flatMapIterable{list->list}
.toSortedList{p1,p2->
(p1?.name?:“”)。与(p2?.name?:“”)相比
}
.订阅({items->
//...
},{可丢弃->
//..
}))
您也可以这样做:
Observable.from(list)
.sorted((o1, o2) -> o1.name.compareTo(o2.name))
.toList()
.subscribe(
sortedList -> sortedList,
error -> error);
科特林:
list.sortBy { it.name }
嗯,你的方式对我很合适。你知道rxjava的toSortedList()函数吗?如何将StatusComparator函数传递给toSortedList()函数。如果您愿意,可以使用。然而,只有当可观察对象中的底层对象是EventParticipant
s,而不是列表本身时,这才有效。按照您编写它的方式,方法getParticipants()
的输出似乎是Observable
。是的,getParticipants()
函数的返回值是Observable
。谢谢你的回答。我正在接受您的帖子。在您的代码段中复制集合的原因是什么?我不想修改通过引用传递给我们的基础列表。一般来说,您希望避免副作用,因为这会使使用您的代码的人生活困难。我复制是为了避免这种副作用。是的,你说得对,谢谢Schedulers.computation()
tips。我认为map()操作应该是flatMap()。