Как преобразовать несколько объектов в один с помощью RxJava? - PullRequest
0 голосов
/ 25 октября 2018

У меня есть Календарь объект, внутри которого есть списки нескольких различных объектов, таких как: Задача , Оценка , WorkOrder и BlockTime .

Итак, чтобы отобразить все эти Календарь события, я планирую создать CalendarItem объект с типом события и добавить это событие.

public class CalendarItem {

private int type;
private Task task;
private Estimate estimate;
private WorkOrder workOrder;
private BlockTime blockTime;

public CalendarItem() {
}
}

У меня есть эта функция RxJava:

Disposable disposable = calendarRepository.getCalendar(startDate, endDate)
    .subscribeOn(Schedulers.io())
    .flatMap((Function<Calendar, Publisher<List<CalendarItem>>>) calendar -> {
      List<Task> tasks = calendar.getTasks();
      List<WorkOrder> workOrders = calendar.getWorkOrders();
      List<BlockTime> blockTimes = calendar.getBlockTimes();
      List<Estimate> estimates = calendar.getEstimates();

      List<CalendarItem> calendarItems = new ArrayList<>();

      if(tasks != null) {
        for(Task t : tasks) {
          CalendarItem item = new CalendarItem();
          item.setType(Constants.CALENDAR_TASK);
          item.setTask(t);
          calendarItems.add(item);
        }
      }

      if(workOrders != null) {
        for(WorkOrder w : workOrders) {
          CalendarItem item = new CalendarItem();
          item.setType(Constants.CALENDAR_WORK_ORDER);
          item.setWorkOrder(w);
          calendarItems.add(item);
        }
      }

      if(estimates != null) {
        for(Estimate e : estimates) {
          CalendarItem item = new CalendarItem();
          item.setType(Constants.CALENDAR_ESTIMATE);
          item.setEstimate(e);
          calendarItems.add(item);
        }
      }

      if(blockTimes != null) {
        for(BlockTime b : blockTimes) {
          CalendarItem item = new CalendarItem();
          item.setType(Constants.CALENDAR_BLOCKED_TIME);
          item.setBlockTime(b);
          calendarItems.add(item);
        }
      }

      return Flowable.just(calendarItems);
    })
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(calendarItems -> view.displayCalendar(calendarItems), view::handleError);

Как я могу улучшить код внутри flatMap () оператора?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

А как насчет изменения CalendarItem для его статического создания вначале?

public class CalendarItem {

    private int type;
    private Task task;
    private Estimate estimate;
    private WorkOrder workOrder;
    private BlockTime blockTime;

    // Change it to private.
    // In the future, we will only create this object through static methods.
    private CalendarItem() {
    }

    public static CalendarItem fromTask(Task t) {
        CalendarItem item = new CalendarItem();
        item.setType(Constants.CALENDAR_TASK);
        item.setTask(t);
        return item;
    }

    public static CalendarItem fromWorkOrder(WorkOrder w) {
        CalendarItem item = new CalendarItem();
        item.setType(Constants.CALENDAR_WORK_ORDER);
        item.setWorkOrder(w);
        return item;
    }

    public static CalendarItem fromEstimate(Estimate e) {
        CalendarItem item = new CalendarItem();
        item.setType(Constants.CALENDAR_ESTIMATE);
        item.setEstimate(e);
        return item;
    }

    public static CalendarItem fromBlockTime(BlockTime b) {
        CalendarItem item = new CalendarItem();
        item.setType(Constants.CALENDAR_BLOCKED_TIME);
        item.setBlockTime(b);
        return item;
    }
    ...
}

Если вы можете использовать Java Optional или Stream, вы можете написать гораздо более лаконичный код.(В Android доступны библиотеки, такие как Lightweight-Stream-API .)

Disposable disposable = calendarRepository.getCalendar(startDate, endDate)
                .subscribeOn(Schedulers.io())
                .map(calendar -> {
                    List<CalendarItem> calendarItems = new ArrayList<>();

                    // tasks
                    calendarItems.addAll(Optional.ofNullable(calendar.getTasks()).map(it -> it.stream().map(CalendarItem::fromTask).collect(toList())).orElse(emptyList()));

                    // workOrders
                    calendarItems.addAll(Optional.ofNullable(calendar.getWorkOrders()).map(it -> it.stream().map(CalendarItem::fromWorkOrder).collect(toList())).orElse(emptyList()));

                    // estimates
                    calendarItems.addAll(Optional.ofNullable(calendar.getEstimates()).map(it -> it.stream().map(CalendarItem::fromEstimate).collect(toList())).orElse(emptyList()));

                    // blockTimes
                    calendarItems.addAll(Optional.ofNullable(calendar.getBlockTimes()).map(it -> it.stream().map(CalendarItem::fromBlockTime).collect(toList())).orElse(emptyList()));

                    return calendarItems;
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(calendarItems -> view.displayCalendar(calendarItems), view::handleError);

Если вы хотите использовать только RxJava, вы также можете использовать код ниже.(Это выглядит немного сложнее.)

Disposable disposable = calendarRepository.getCalendar(startDate, endDate)
                .subscribeOn(Schedulers.io())
                .map(calendar -> {
                    List<Task> tasks = calendar.getTasks();
                    List<WorkOrder> workOrders = calendar.getWorkOrders();
                    List<BlockTime> blockTimes = calendar.getBlockTimes();
                    List<Estimate> estimates = calendar.getEstimates();

                    List<CalendarItem> calendarItems = new ArrayList<>();

                    // tasks
                    if (tasks != null) {
                        calendarItems.addAll(
                                Observable.fromIterable(tasks)
                                        .map(CalendarItem::fromTask)
                                        .toList()
                                        .blockingGet()
                        );
                    }

                    // workOrders
                    if (workOrders != null) {
                        calendarItems.addAll(
                                Observable.fromIterable(workOrders)
                                        .map(CalendarItem::fromWorkOrder)
                                        .toList()
                                        .blockingGet()
                        );
                    }

                    // estimates
                    if (blockTimes != null) {
                        calendarItems.addAll(
                                Observable.fromIterable(estimates)
                                        .map(CalendarItem::fromEstimate)
                                        .toList()
                                        .blockingGet()
                        );
                    }

                    // blockTimes
                    if (blockTimes != null) {
                        calendarItems.addAll(
                                Observable.fromIterable(blockTimes)
                                        .map(CalendarItem::fromBlockTime)
                                        .toList()
                                        .blockingGet()
                        );
                    }

                    return calendarItems;
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(calendarItems -> view.displayCalendar(calendarItems), view::handleError);
0 голосов
/ 25 октября 2018

Один из способов - использовать более функциональный стиль, например:

.flatMap(calendar -> {
    Observable<CalendarItem> tasks = Observable
        .just(Optional.ofNullable(calendar.getTasks()).orElse(Collections.emptyList()))
        .map(task -> {
            CalendarItem item = new CalendarItem();
            item.setType(Constants.CALENDAR_TASK);
            item.setTask(task);
            return item;
        });

    Observable<CalendarItem> workOrders = Observable
        .just(Optional.ofNullable(calendar.getWorkOrders()).orElse(Collections.emptyList()))
        .map(workOrder -> {
            CalendarItem item = new CalendarItem();
            item.setType(Constants.CALENDAR_WORK_ORDER);
            item.setWorkOrder(task);
            return item;
        });

    // estimates and blockTimes

    return tasks.mergeWith(workOrders).mergeWith(estimates).mergeWith(blockTimes);
});
...