android 带比较器的 rxjava 排序列表 class
android rxjava sort list with comparator class
我开始在我的 android 项目中使用 rxjava。我需要对 api 调用返回的事件列表进行排序。我写了比较器 class 来排序列表:
public class EventParticipantComparator {
public static class StatusComparator implements Comparator<EventParticipant> {
@Override
public int compare(EventParticipant participant1, EventParticipant participant2) {
return participant1.getStatus() - participant2.getStatus();
}
}
}
我可以将此 class 与 classic Collections class.
一起使用
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) {
}
});
如果我没有阅读 Collections.sort()
, I would have recommended something like map
(list -> Collections.sort (list, comparator))
的 Javadoc 将其转换为排序数组;这里,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>
进行排序。
此解决方案与已接受的答案类似,但使用 Rx 运算符 1) 将数组拆分为对象 2) 按实例排序 Comparable 实现 3) 在专用计算线程上执行;
dataManager.getEventImplementer().getParticipants(event.getId())
.flatMap(Observable::from)
.toSortedList()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(sortedList -> {...}, error -> {...});
请注意,对于 network/disk 写入,最好使用 Schedulers.io,对于排序等计算,Schedulers.computation
我假设 getParticipants()
方法 returns Observable<List<EventPartcipant>>
.
在下面的代码片段中,我首先使用 flatMap()
运算符将 Observable<List<EventPartcipant>>
转换为 Observable<EventParticipant>
。这个 observable 将一次发射每个 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.
}
});
还有一种排序列表的方法
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.
});
Kotlin 版本:
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 ->
//..
}))
你也可以这样做:
Observable.from(list)
.sorted((o1, o2) -> o1.name.compareTo(o2.name))
.toList()
.subscribe(
sortedList -> sortedList,
error -> error);
科特林:
list.sortBy { it.name }
我开始在我的 android 项目中使用 rxjava。我需要对 api 调用返回的事件列表进行排序。我写了比较器 class 来排序列表:
public class EventParticipantComparator {
public static class StatusComparator implements Comparator<EventParticipant> {
@Override
public int compare(EventParticipant participant1, EventParticipant participant2) {
return participant1.getStatus() - participant2.getStatus();
}
}
}
我可以将此 class 与 classic Collections class.
一起使用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) {
}
});
如果我没有阅读 Collections.sort()
, I would have recommended something like map
(list -> Collections.sort (list, comparator))
的 Javadoc 将其转换为排序数组;这里,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>
进行排序。
此解决方案与已接受的答案类似,但使用 Rx 运算符 1) 将数组拆分为对象 2) 按实例排序 Comparable 实现 3) 在专用计算线程上执行;
dataManager.getEventImplementer().getParticipants(event.getId())
.flatMap(Observable::from)
.toSortedList()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(sortedList -> {...}, error -> {...});
请注意,对于 network/disk 写入,最好使用 Schedulers.io,对于排序等计算,Schedulers.computation
我假设 getParticipants()
方法 returns Observable<List<EventPartcipant>>
.
在下面的代码片段中,我首先使用 flatMap()
运算符将 Observable<List<EventPartcipant>>
转换为 Observable<EventParticipant>
。这个 observable 将一次发射每个 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.
}
});
还有一种排序列表的方法
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.
});
Kotlin 版本:
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 ->
//..
}))
你也可以这样做:
Observable.from(list)
.sorted((o1, o2) -> o1.name.compareTo(o2.name))
.toList()
.subscribe(
sortedList -> sortedList,
error -> error);
科特林:
list.sortBy { it.name }