按日期将事件列表分组到事件字典中
Group a list of events into a dictionary of events by date
我一直在努力学习 RxJava2,但我一直在努力学习 RxJava2..
所以,我有一个表示事件的结构,如下所示:
class Event{
public Date when;
public String eventName;
}
我在某个地方查询了我想按日期分组的存储库中的事件列表。
因此,给定如下事件列表:
- 6 月的活动 1
- 6 月的活动 2
- 7 月的活动 3
- 8 月的活动 4
- 8 月的活动 5
我想将它们分组以便
- 六月
- 事件 1
- 事件 2
- 七月
- 活动 3
- 八月
- 事件 4
- 事件 5
到目前为止,在我看来,我所拥有的是非常丑陋的,我很确定我已经结束了-"engineering"这个...
repository.getAllEvents()
.toObservable()
.flatMap(new Function<Events, Observable<Event>>() {
@Override
public Observable<Event> apply(@NonNull Events events) throws Exception {
return Observable.fromIterable(events.getEvents());
}
})
.groupBy(new Function<Event, Date>() {
@Override
public Date apply(@NonNull Event event) throws Exception {
return event.when;
}
})
.flatMap(new Function<GroupedObservable<Date, Event>, Observable<Object>>() {
@Override
public Observable<Object> apply(@NonNull GroupedObservable<Date, Event> dateEventGroupedObservable) throws Exception {
final Date key = dateEventGroupedObservable.getKey();
return dateEventGroupedObservable.toList().toObservable().flatMap(new Function<List<Event>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(@NonNull List<Event> events) throws Exception {
return Observable.just(new Pair<Date, List<Event>>(key, events));
}
});
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
到目前为止,这给了我一个提供 Pair> 的可观察对象,但如您所见,它被转换为 Object,老实说,我无法理解泛型地狱 -.-'
关于我如何解决这个问题的任何提示?
谢谢
您只需使用 collect
运算符即可实现此目的:
repository.getAllEvents()
.flatMapIterable(events -> events.getEvents())
.collect(() -> new HashMap<Date, List<Event>>(),
(map, event) -> putEventIntoMap(map, event)
)
...
没有 lambda:
// I assume that getAllEvents returns Events class
repository.getAllEvents()
.flatMapIterable(new Function<Events, Iterable<? extends Event>>() {
@Override
public Iterable<? extends Event> apply(@NonNull Events events) throws Exception {
return events.getEvents();
}
})
.collect(new Callable<HashMap<Date, List<Event>>>() {
@Override
public HashMap<Date, List<Event>> call() throws Exception {
return new HashMap<Date, List<Event>>();
}}, new BiConsumer<HashMap<Date, List<Event>>, Event>() {
@Override
public void accept(@NonNull HashMap<Date, List<Event>> map, @NonNull Event event) throws Exception {
putEventIntoMap(map, event);
}}
)
...
将事件放入地图的方法:
private void putEventIntoMap(HashMap<Date, List<Event>> map, Event event) {
if (map.containsKey(event.when)) {
map.get(event.when).add(event);
} else {
List<Event> list = new ArrayList<>();
list.add(event);
map.put(event.when, list);
}
}
基于,我能够将其改编成以下工作解决方案:
repository.getAllEvents()
// Convert the Single<Events> into an Observable<Events>
.toObservable()
// Transform the stream Events into a List<Event> stream / observable
.flatMapIterable(new Function<Events, List<Event>>() {
@Override
public List<Event> apply(@NonNull Events events) throws Exception {
return events.getEvents();
}
})
// Group each Event from the List<Event> by when (date)
.groupBy(new Function<Event, Date>() {
@Override
public Date apply(@NonNull Event event) throws Exception {
return event.when;
}
})
// For each grouped stream (not sure if its correct to call it like this)
// Lets generate a new stream that is a Pair<Date, List<Event>>
.flatMap(new Function<GroupedObservable<Date, Event>, Observable<Pair<Date, List<Event>>>>() {
@Override
public Observable<Pair<Date, List<Event>>> apply(@NonNull GroupedObservable<Date, Event> dateEventGroupedObservable) throws Exception {
final Date key = dateEventGroupedObservable.getKey();
// toList() takes a big role here since it is forcing
// for the dateEventGroupedObservable to complete and only then
// streaming a Single<List<Event>> which is why I convert it back to observable
return dateEventGroupedObservable.toList().toObservable().flatMap(new Function<List<Event>, Observable<Pair<Date, List<Event>>>>() {
@Override
public Observable<Pair<Date, List<Event>>> apply(@NonNull List<Event> events) throws Exception {
return Observable.just(new Pair<Date, List<Event>>(key, events));
}
});
}
})
// We can now collect all streamed pairs of (Date, List<Event>)
// into an HashMap
.collect(new Callable<HashMap<Date, List<Event>>>() {
@Override
public HashMap<Date, List<Event>> call() throws Exception {
return new HashMap<Date, List<Event>>();
}
}, new BiConsumer<HashMap<Date, List<Event>>, Pair<Date, List<Event>>>() {
@Override
public void accept(@NonNull HashMap<Date, List<Event>> dateListHashMap, @NonNull Pair<Date, List<Event>> dateListPair) throws Exception {
dateListHashMap.put(dateListPair.first, new ArrayList<Event>(dateListPair.second));
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new SingleObserver<HashMap<Date, List<Event>>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(HashMap<Date, List<Event>> dateListHashMap) {
}
@Override
public void onError(Throwable e) {
}
});
是的,它很长而且很难看,但我很确定使用 lambda 会更好看。现在,问题是......这段代码用于提供回收器视图适配器,所以我想知道以命令方式简单地执行此操作是否会更容易......哦,好吧,服务于研究目的:)
我一直在努力学习 RxJava2,但我一直在努力学习 RxJava2..
所以,我有一个表示事件的结构,如下所示:
class Event{
public Date when;
public String eventName;
}
我在某个地方查询了我想按日期分组的存储库中的事件列表。
因此,给定如下事件列表:
- 6 月的活动 1
- 6 月的活动 2
- 7 月的活动 3
- 8 月的活动 4
- 8 月的活动 5
我想将它们分组以便
- 六月
- 事件 1
- 事件 2
- 七月
- 活动 3
- 八月
- 事件 4
- 事件 5
到目前为止,在我看来,我所拥有的是非常丑陋的,我很确定我已经结束了-"engineering"这个...
repository.getAllEvents()
.toObservable()
.flatMap(new Function<Events, Observable<Event>>() {
@Override
public Observable<Event> apply(@NonNull Events events) throws Exception {
return Observable.fromIterable(events.getEvents());
}
})
.groupBy(new Function<Event, Date>() {
@Override
public Date apply(@NonNull Event event) throws Exception {
return event.when;
}
})
.flatMap(new Function<GroupedObservable<Date, Event>, Observable<Object>>() {
@Override
public Observable<Object> apply(@NonNull GroupedObservable<Date, Event> dateEventGroupedObservable) throws Exception {
final Date key = dateEventGroupedObservable.getKey();
return dateEventGroupedObservable.toList().toObservable().flatMap(new Function<List<Event>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(@NonNull List<Event> events) throws Exception {
return Observable.just(new Pair<Date, List<Event>>(key, events));
}
});
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
到目前为止,这给了我一个提供 Pair> 的可观察对象,但如您所见,它被转换为 Object,老实说,我无法理解泛型地狱 -.-'
关于我如何解决这个问题的任何提示?
谢谢
您只需使用 collect
运算符即可实现此目的:
repository.getAllEvents()
.flatMapIterable(events -> events.getEvents())
.collect(() -> new HashMap<Date, List<Event>>(),
(map, event) -> putEventIntoMap(map, event)
)
...
没有 lambda:
// I assume that getAllEvents returns Events class
repository.getAllEvents()
.flatMapIterable(new Function<Events, Iterable<? extends Event>>() {
@Override
public Iterable<? extends Event> apply(@NonNull Events events) throws Exception {
return events.getEvents();
}
})
.collect(new Callable<HashMap<Date, List<Event>>>() {
@Override
public HashMap<Date, List<Event>> call() throws Exception {
return new HashMap<Date, List<Event>>();
}}, new BiConsumer<HashMap<Date, List<Event>>, Event>() {
@Override
public void accept(@NonNull HashMap<Date, List<Event>> map, @NonNull Event event) throws Exception {
putEventIntoMap(map, event);
}}
)
...
将事件放入地图的方法:
private void putEventIntoMap(HashMap<Date, List<Event>> map, Event event) {
if (map.containsKey(event.when)) {
map.get(event.when).add(event);
} else {
List<Event> list = new ArrayList<>();
list.add(event);
map.put(event.when, list);
}
}
基于
repository.getAllEvents()
// Convert the Single<Events> into an Observable<Events>
.toObservable()
// Transform the stream Events into a List<Event> stream / observable
.flatMapIterable(new Function<Events, List<Event>>() {
@Override
public List<Event> apply(@NonNull Events events) throws Exception {
return events.getEvents();
}
})
// Group each Event from the List<Event> by when (date)
.groupBy(new Function<Event, Date>() {
@Override
public Date apply(@NonNull Event event) throws Exception {
return event.when;
}
})
// For each grouped stream (not sure if its correct to call it like this)
// Lets generate a new stream that is a Pair<Date, List<Event>>
.flatMap(new Function<GroupedObservable<Date, Event>, Observable<Pair<Date, List<Event>>>>() {
@Override
public Observable<Pair<Date, List<Event>>> apply(@NonNull GroupedObservable<Date, Event> dateEventGroupedObservable) throws Exception {
final Date key = dateEventGroupedObservable.getKey();
// toList() takes a big role here since it is forcing
// for the dateEventGroupedObservable to complete and only then
// streaming a Single<List<Event>> which is why I convert it back to observable
return dateEventGroupedObservable.toList().toObservable().flatMap(new Function<List<Event>, Observable<Pair<Date, List<Event>>>>() {
@Override
public Observable<Pair<Date, List<Event>>> apply(@NonNull List<Event> events) throws Exception {
return Observable.just(new Pair<Date, List<Event>>(key, events));
}
});
}
})
// We can now collect all streamed pairs of (Date, List<Event>)
// into an HashMap
.collect(new Callable<HashMap<Date, List<Event>>>() {
@Override
public HashMap<Date, List<Event>> call() throws Exception {
return new HashMap<Date, List<Event>>();
}
}, new BiConsumer<HashMap<Date, List<Event>>, Pair<Date, List<Event>>>() {
@Override
public void accept(@NonNull HashMap<Date, List<Event>> dateListHashMap, @NonNull Pair<Date, List<Event>> dateListPair) throws Exception {
dateListHashMap.put(dateListPair.first, new ArrayList<Event>(dateListPair.second));
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new SingleObserver<HashMap<Date, List<Event>>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(HashMap<Date, List<Event>> dateListHashMap) {
}
@Override
public void onError(Throwable e) {
}
});
是的,它很长而且很难看,但我很确定使用 lambda 会更好看。现在,问题是......这段代码用于提供回收器视图适配器,所以我想知道以命令方式简单地执行此操作是否会更容易......哦,好吧,服务于研究目的:)