【问题标题】:group list of objects by date and sort them time using rxjava按日期分组对象列表并使用 rxjava 对它们进行时间排序
【发布时间】:2015-06-20 05:12:28
【问题描述】:

我有一份餐厅预订清单。 我想按一年中的一天对它们进行分组,并按那天的时间对它们进行排序。 我怎样才能使用 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 预订

【问题讨论】:

    标签: java functional-programming reactive-programming rx-java


    【解决方案1】:

    要使用 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 吗?
    【解决方案2】:

    由于您已经拥有完整的预订列表(即 List&lt;Reservation&gt;,而不是 Observable&lt;Reservation&gt;),因此您在这里并不需要 RxJava ——您可以使用 Java 8 流/集合 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)));
    

    【讨论】:

      猜你喜欢
      • 2020-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-06
      • 1970-01-01
      • 2019-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多