Есть метод, в котором алгоритм прописан через обычную итерацию по List:
public static List<UserMealWithExceed> getFilteredWithExceeded(List<UserMeal> mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
Map<LocalDate, Integer> caloriesOfDayMap = new HashMap<>();
List<UserMealWithExceed> userList = new ArrayList<>();
LocalDate date;
LocalTime time;
for (UserMeal um : mealList) {
date = TimeUtil.toLocalDate(um.getDateTime());
Integer calories = um.getCalories();
caloriesOfDayMap.merge(date, calories, Integer::sum);
}
for (UserMeal um : mealList) {
time = TimeUtil.toLocalTime(um.getDateTime());
if (TimeUtil.isBetween(time, startTime, endTime)) {
date = TimeUtil.toLocalDate(um.getDateTime());
int caloriesOfDate = caloriesOfDayMap.get(date);
boolean isExceeds = caloriesOfDate >= caloriesPerDay;
userList.add(new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), isExceeds));
}
}
return userList;
}
Задача - реализовать алгоритм через Stream API. Проблема - не могу сообразить, как использовать stream().collect именно для выполнения функции merge(). Прошу помощи
public static List<UserMealWithExceed> getFilteredWithExceeded(List<UserMeal> mealList,
LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
final Map<LocalDate, Integer> caloriesOfDayMap =
mealList.stream().collect(Collectors.toMap(um->um.getDateTime().toLocalDate(), um->um.getCalories(), Integer::sum));
return mealList.stream()
.filter(um -> um.getDateTime().toLocalTime().isAfter(startTime)
&& um.getDateTime().toLocalTime().isBefore(endTime))
.map(um->createUserMealWithExceed(caloriesOfDayMap, um, caloriesPerDay))
.collect(Collectors.toList());
}
private static UserMealWithExceed createUserMealWithExceed(Map<LocalDate, Integer> caloriesOfDayMap, UserMeal um, int caloriesPerDay){
boolean isExceeds = caloriesOfDayMap.get(um.getDateTime().toLocalDate()) >= caloriesPerDay;
return new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), isExceeds);
}
Полагаю, что в классе UserMeal dateTime имеет тип LocalDateTime (иначе это странно). В этом случае никаких дополнительных утилит в виде TimeUtil не требуется, все уже есть из коробки в пакете java.time.
public static List<UserMealWithExceed> getFilteredWithExceeded(List<UserMeal> mealList,
LocalTime startTime,
LocalTime endTime,
int caloriesPerDay) {
Map<LocalDate, Integer> caloriesOfDayMap = mealList.stream()
.collect(Collectors.groupingBy(um -> TimeUtil.toLocalDate(um.getDateTime()),
Collectors.summingInt(UserMeal::getCalories)));
return mealList.stream()
.filter(um -> TimeUtil.isBetween(TimeUtil.toLocalTime(um.getDateTime()),
startTime,
endTime))
.map(um -> new UserMealWithExceed(um.getDateTime(),
um.getDescription(),
um.getCalories(),
caloriesOfDayMap.get(TimeUtil.toLocalDate(um.getDateTime()) >= caloriesPerDay))
.collect(Collectors.toList());
}
Разумеется, можно насоздавать для каждой операции нужные функциональные объекты и запихнуть громоздкий код в них, будет красивее выглядеть.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
От сервера с помощью Retrofit я получаю данные в виде:
Задача: На числовой прямой дан отрезок [3;8]Требуется определить, принадлежит ли точка x данному отрезку
Пытаясь подключится к localhost:3000 выдает ошибку (в названии), я пробовал подключать вебсокет по адресу "localhost:3000", "localhost", "3000", все кроме localhost выдает...