android rxjava sort list with comparator class
This solution is similar to the accepted answer, but uses Rx operators to 1) split array into objects 2) sort by the instances Comparable implementation 3) do it on a dedicated computation thread;
dataManager.getEventImplementer().getParticipants(event.getId())
.flatMap(Observable::from)
.toSortedList()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(sortedList -> {...}, error -> {...});
Note that it's preferred to use Schedulers.io for network/disk writes, Schedulers.computation for computations like sorting
If I had not read the Javadoc for Collections.sort()
, I would have recommended something like map
(list -> Collections.sort (list, comparator))
to convert it into a sorted array; here, map
is the observable mapper.
However, the sort
method above is an in-place sorting algorithm, which affect the underlying array rather than returning the fully sorted array. So instead you should do something like this:
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.
});
This will sort each incoming List<EventParticipant>
individually and asynchronously.
I am assuming the getParticipants()
method returns Observable<List<EventPartcipant>>
.
In the below snippet, I first convert the Observable<List<EventPartcipant>>
to Observable<EventParticipant>
using the flatMap()
operator. This observable will emit each EventParticipant
one at a time. Now by using the toSortedList()
operator I can act on two EventParticipant
object at a time just like Comparator<EventParticipant>::compareTo
expects.
In the other solutions, sorting operators are applied after .observeOn(AndroidSchedulers.mainThread())
, which means the actual sorting happens on the UI thread.
I modified this to let the API call execute on IO scheduler, sorting on the computation scheduler and finally your sorted list on the UI thread.
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.
}
});