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