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

时间:2016-10-26 16:19:45

标签: android sorting collections 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();
        }
    }
}

我可以将这个类与经典的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) {

                    }
                });

5 个答案:

答案 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 ->
        //..
    }))