У меня есть класс смены, который возвращает информацию о смене.
public class Shift {
@PlanningId
private String id;
private LocalDateTime start;
private LocalDateTime end;
public Long getShiftDuration() {
long minutes = ChronoUnit.MINUTES.between(start, end);
return minutes;
}
public String getBusinessDate() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String dateStr = getStart().toLocalDate().format(formatter);
return dateStr;
}
}
Затем у меня есть класс DaySettingFlat, который содержит список дат, которые нам нужны для расчета суммы продолжительности смен. Дата, указанная в DaySettingFlat, содержит переменную businessDate, которая будет содержать дату. С помощью этого значения даты мы должны суммировать длительности коллекции Shift, соответствующие businessDate.
public class DaySettingFlat {
String businessDate;
Integer sumOfShiftDuration;
}
Оба класса зарегистрированы как @ProblemFactCollectionProperty. Теперь для каждой записи DaySettingFlat нам нужно суммировать продолжительность смен для даты, хранящейся в businessDate. И Shift, и DaySettingFlat используются как коллекция.
Я попробовал следующее, но это не работает, выдает ошибку компиляции:
Constraint daySettingStandardNumberOfHours(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(DaySettingFlat.class)
.join(Shift.class, equal(DaySettingFlat::getBusinessDate, Shift::getStartDate))
//Getting error on group by
.groupBy(Shift::getStartDate,
ConstraintCollectors.toList(),
ConstraintCollectors.sumLong(Shift::getShiftDuration))
.penalize(HardMediumSoftScore.ONE_HARD, (date, list, totalDuration)->{
return totalDuration;
}).asConstraint("daySettingStandardNumberOfHours");
}
Кроме того, я бы использовал Duration для продолжительности смены и для ее суммы, для более четкого кода, чем вы получаете с int (и Integer, не знаю, почему вы ввели туда объект).




Причина, по которой это не работает, заключается в том, что у вас есть BiConstraintStream, поэтому вам нужно предоставить функцию, которая принимает и DaySettingFlat, и Shift:
Constraint daySettingStandardNumberOfHours(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(DaySettingFlat.class)
.join(Shift.class, equal(DaySettingFlat::getBusinessDate, Shift::getStartDate))
.groupBy((day, shift) -> shift.getStartDate(),
ConstraintCollectors.toList((day, shift) -> day),
ConstraintCollectors.sumLong((day, shift) -> shift.getShiftDuration()))
.penalize(HardMediumSoftScore.ONE_HARD, (date, list, totalDuration)->{
return totalDuration;
}).asConstraint("daySettingStandardNumberOfHours");
}
Список что-нибудь делает? Он не используется в предоставленном вами ограничении. Если нет, то рекомендую удалить.
И примечание: вы можете использовать sumDuration javadoc.io/static/ai.timefold.solver/timefold-solver-core/…, если вы изменили getShiftDuration, чтобы вернуть Duration.
С вашей репутацией и, следовательно, опытом работы с SO вы должны знать, что фраза «это не работает» на самом деле не поможет. Можете ли вы уточнить, в чем именно это не работает?