带有比较器类的android rxjava排序列表

oka*_*ose 10 sorting collections android rx-java rx-android

我开始在我的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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以将这个类与经典的Collections类一起使用.

Collections.sort(participants, new EventParticipantComparator.StatusComparator());
Run Code Online (Sandbox Code Playgroud)

如何通过反应方式实现这种情况?如果有任何方式异步排序列表,我会更喜欢这种方式.

没有排序列表的反应方式:

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) {

                    }
                });
Run Code Online (Sandbox Code Playgroud)

小智 14

如果我没有阅读Javadoc Collections.sort(),我会建议将其转换为排序数组; 这里是可观察的映射器.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.
            });
Run Code Online (Sandbox Code Playgroud)

这将List<EventParticipant>单独和异步地对每个传入进行排序.


Pär*_*sen 13

此解决方案类似于已接受的答案,但使用Rx运算符1)将数组拆分为对象2)按实例排序可比较实现3)在专用计算线程上执行此操作;

dataManager.getEventImplementer().getParticipants(event.getId())
    .flatMap(Observable::from)
    .toSortedList()
    .subscribeOn(Schedulers.computation())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(sortedList -> {...}, error -> {...});
Run Code Online (Sandbox Code Playgroud)

请注意,首选使用Schedulers.io进行网络/磁盘写入,使用Schedulers.computation进行排序等计算


小智 7

我假设getParticipants()方法返回Observable<List<EventPartcipant>>.

在下面的代码片段,我首先转换Observable<List<EventPartcipant>>Observable<EventParticipant>使用的flatMap()运营商.这个可观察者将一次发射每EventParticipant一个.现在通过使用toSortedList()运算符,我可以EventParticipantComparator<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.
                }
    });
Run Code Online (Sandbox Code Playgroud)


Dr.*_*cky 6

科特林版本:


    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 ->
            //..
        }))
Run Code Online (Sandbox Code Playgroud)


ale*_*bel 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.
        });
Run Code Online (Sandbox Code Playgroud)