按日期分组并使用RxJava按时间对对象进行排序的组列表

4

我有一份餐厅预订列表。 我想按年份的日期分组,并按当天的时间对它们进行排序。 如何使用rxjava实现?

List reservations;

class Reservation {
   public String guestName;
   public long time; //time in milliseconds
}

输出

  • 2015年3月5日
    • 20:00预订
    • 22:00预订
  • 2015年3月8日
    • 16:00预订
2个回答

8
要使用RxJava完成这个任务,您首先需要通过时间进行排序(使用toSortedList),然后在flatMap中执行手动分组,并输出一个Observable<List<Reservation>>,从而得到每一天的预订信息。
Observable.from(reservations)
    .toSortedList(new Func2<Reservation, Reservation, Integer>() {
        @Override
        public Integer call(Reservation reservation, Reservation reservation2) {
            return Long.compare(reservation.time, reservation2.time);
        }
    })
    .flatMap(new Func1<List<Reservation>, Observable<List<Reservation>>>() {
        @Override
        public Observable<List<Reservation>> call(List<Reservation> reservations) {
            List<List<Reservation>> allDays = new ArrayList<>();
            List<Reservation> singleDay = new ArrayList<>();
            Reservation lastReservation = null;
            for (Reservation reservation : reservations) {
                if (differentDays(reservation, lastReservation)) {
                    allDays.add(singleDay);
                    singleDay = new ArrayList<>();
                }
                singleDay.add(reservation);
                lastReservation = reservation;
            }
            return Observable.from(allDays);
        }
    })
    .subscribe(new Action1<List<Reservation>>() {
        @Override
        public void call(List<Reservation> oneDaysReservations) {
            // You will get each days reservations, in order, in here to do with as you please.
        }
    });

我留下differentDays方法作为读者的练习。

很好的例子@Adam。不过我有一个问题,我们可以使用groupBy代替flatMap吗? - Ritt

4

由于您已拥有完整的预订列表(即List<Reservation>,而不是Observable<Reservation>),因此在此处您不需要使用RxJava——您可以使用Java 8 stream/collections API完成所需操作:

Map<Calendar, List<Reservation>> grouped = reservations
    .stream()
    .collect(Collectors.groupingBy(x -> {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(x.time);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal;
    }));

正如你所看到的,它所做的就是按一年中的日期进行groupingBy。如果您的初始数据使用Calendar而不是long作为时间戳,那么这看起来甚至更简单,像这样:

Map<Calendar, List<Reservation>> grouped = reservations
    .stream()
    .collect(Collectors.groupingBy(x -> x.time.get(Calendar.DAY_OF_YEAR)));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接