按日期将事件列表分组到事件字典中

时间:2017-03-21 01:50:58

标签: java reactive-programming rx-java2

我一直在努力学习RxJava2,而且我一直在努力学习这个......

所以,我有一个代表事件的结构,如下所示:

onsubmit="return myfunc()"

在某个地方,我查询了我希望按日期分组的存储库中的事件列表。

所以,给出一个事件列表,如:

  • 6月的Event1
  • 6月的Event2
  • 7月的Event3
  • 8月的Event4
  • 8月的Event5

我想将它们分组以便

  • 六月
    • 事件1
    • 事件2
  • 七月
    • EVENT3
  • 八月
    • EVENT4
    • Event5

到目前为止,我认为非常难看,我很确定我已经结束了 - "工程"此...

class Event{
    public Date when;
    public String eventName;
}

到目前为止,这给了我一个可以提供一对>的观察结果。但正如你可以看到它被转换为对象我真的无法理解泛型地狱 - .-'

关于我如何处理此问题的任何提示?

由于

2 个答案:

答案 0 :(得分:2)

您只需使用collect运算符即可实现此目的:

repository.getAllEvents()
    .flatMapIterable(events -> events.getEvents())
    .collect(() -> new HashMap<Date, List<Event>>(), 
             (map, event) -> putEventIntoMap(map, event)
    )
    ...

没有lambdas:

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

答案 1 :(得分:0)

基于@Maxim Ostrovidov answer,我能够将其调整为以下工作解决方案:

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

        }
    });

是的,它很长很丑,但我很确定使用lambdas这会更好看。现在,事情就是......这个代码用于提供一个回收站视图适配器,所以我想知道以一种必要的方式做到这一点是不是更容易......哦,为研究目的服务:)