我开始在我的android项目中使用rxjava。我需要从api调用中对返回的事件列表进行排序。我写了比较类来排序列表:
public class EventParticipantComparator {
public static class StatusComparator implements Comparator<EventParticipant> {
@Override
public int compare(EventParticipant participant1, EventParticipant participant2) {
return participant1.getStatus() - participant2.getStatus();
}
}
}
我可以将这个类与经典的Collections类一起使用。
Collections.sort(participants, new EventParticipantComparator.StatusComparator());
如何以反应方式实现这种情况? 如果有任何方法可以异步对列表进行排序,我会更喜欢这种方式。
没有排序列表的反应方式:
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) {
}
});
答案 0 :(得分:14)
如果我没有阅读Collections.sort()
的Javadoc,我会推荐map
(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.
});
这将单独和异步地对每个传入的List<EventParticipant>
进行排序。
答案 1 :(得分:13)
此解决方案与接受的答案类似,但使用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进行排序等计算
答案 2 :(得分:7)
我假设getParticipants()
方法返回Observable<List<EventPartcipant>>
。
在下面的代码段中,我首先使用Observable<List<EventPartcipant>>
运算符将Observable<EventParticipant>
转换为flatMap()
。这个可观察量将一次发出一个EventParticipant
个。现在,通过使用toSortedList()
运算符,我可以像EventParticipant
期望的那样一次对两个Comparator<EventParticipant>::compareTo
对象执行操作。
在其他解决方案中,排序运算符在.observeOn(AndroidSchedulers.mainThread())
之后应用,这意味着实际排序发生在UI线程上。
我修改了这个,让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.
}
});
答案 3 :(得分:5)
还有一种方法可以对列表进行排序
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.
});
答案 4 :(得分:3)
科特琳版本:
disposable.add(interactor.getItemList() //It returns Observable<ItemListResponseModel>
.compose(threadTransformer.applySchedulers())
.flatMapIterable { list -> list }
.toSortedList { p1, p2 ->
(p1?.name ?: "").compareTo(p2?.name ?: "")
}
.subscribe({ items ->
//...
}, { throwable ->
//..
}))