List<UserMeal> meals = Arrays.asList(
new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 10, 0), "Завтрак", 500),
new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 13, 0), "Обед", 1000),
new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 30, 20, 0), "Ужин", 500),
new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 0, 0), "Еда на граничное значение", 100),
new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 10, 0), "Завтрак", 1000),
new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 13, 0), "Обед", 500),
new UserMeal(LocalDateTime.of(2020, Month.JANUARY, 31, 20, 0), "Ужин", 410)
);
LocalTime startTime = LocalTime.of(7, 0);
LocalTime endTime = LocalTime.of(12, 0);
int caloriesPerDay = 2000;
Красивое решение
Map<LocalDate, Integer> mailsCaloriesSum = meals.stream()
.collect(Collectors.groupingBy(UserMeal::getDate, Collectors.summingInt(UserMeal::getCalories)));
return meals.stream()
.filter(um -> {
return TimeUtil.isBetweenHalfOpen(um.getTime(), startTime, endTime);
})
.map(um -> creatTo(um, mailsCaloriesSum.get(um.getDate()) > caloriesPerDay))
.collect(Collectors.toList());
Рабочий вариант
Map<LocalDate, Integer> mailsCaloriesSum = new HashMap<>();
List<UserMealWithExcess> mealsFilter = meals.stream()
.filter(um -> {
if (mailsCaloriesSum.containsKey(um.getDate())) {
mailsCaloriesSum.put(um.getDate(), mailsCaloriesSum.get(um.getDate()) + um.getCalories());
} else {
mailsCaloriesSum.put(um.getDate(), um.getCalories());
}
return um.getDateTime().toLocalTime().isAfter(startTime) && um.getTime().isBefore(endTime);
}).collect(Collectors.toList()).stream().map(um -> {
boolean b = mailsCaloriesSum.getOrDefault(um.getDate(), 0) > caloriesPerDay ? true : false;
return new UserMealWithExcess(um.getDateTime(), um.getDescription(), um.getCalories(), b);
}).collect(Collectors.toList());
mealsFilter.forEach(System.out::println);
Выдаст ошибку
local variables referenced from a lambda expression must be final or effectively final
на mailsCaloriesSum
Map<LocalDate, Integer> mailsCaloriesSum = new HashMap<>();
mailsCaloriesSum = meals.stream()
.collect(Collectors.groupingBy(UserMeal::getDate, Collectors.summingInt(UserMeal::getCalories)));
List<UserMealWithExcess> mealsFilter = meals.stream()
.filter(um -> {
return TimeUtil.isBetweenHalfOpen(um.getTime(), startTime, endTime);
})
.map( um -> {
return new UserMealWithExcess(um.getDateTime(), um.getDescription(), um.getCalories(), (mailsCaloriesSum.getOrDefault(um.getDate(), 0) > caloriesPerDay));
})
.collect(Collectors.toList());
Если сделать так
Map<LocalDate, Integer> mailsCaloriesSum = new HashMap<>() = meals.stream()
.collect(Collectors.groupingBy(UserMeal::getDate, Collectors.summingInt(UserMeal::getCalories)));
всё будет работать.