Java 8+Spring Boot住宿预订API:预订日期重叠校验问题求助
修复日期重叠检测逻辑 & 优化建议
首先,咱们先明确问题核心:你的isAvailableBetween方法之所以漏掉跨多个预订的重叠情况,大概率是日期重叠的判断条件写错了,或者用了错误的Stream终止操作。正确的思路应该是:只要新预订和住宿的任意一个已有预订存在日期重叠,就不允许添加——所以我们需要用noneMatch来确保没有任何一个预订符合重叠条件。
修复后的Stream实现
先给出修复后的代码,这里假设你用的是Java 8+推荐的LocalDate处理日期:
public boolean isAvailableBetween(LocalDate newCheckin, LocalDate newCheckout) { // 先校验新预订的日期合法性:入住日必须早于退房日 if (newCheckin.isAfter(newCheckout) || newCheckin.isEqual(newCheckout)) { return false; } // 核心逻辑:没有任何一个已有预订和新预订重叠,才返回可用 return this.bookings.stream() .noneMatch(booking -> // 日期重叠的核心判断条件(覆盖所有重叠场景) newCheckin.isBefore(booking.getCheckout()) && newCheckout.isAfter(booking.getCheckin()) ); }
为什么这个逻辑能解决问题?
这个重叠判断条件newCheckin < booking.checkout && newCheckout > booking.checkin能覆盖所有可能的重叠场景:
- 新预订完全包含在某个已有预订的日期范围内
- 已有预订完全包含在新预订的日期范围内
- 新预订的入住日在某个已有预订内,退房日在外面
- 新预订的退房日在某个已有预订内,入住日在外面
不管新预订跨多少个已有预订,只要和其中任何一个存在重叠,noneMatch就会返回false,直接判定不可用,完美解决你遇到的漏洞。
进一步优化建议
1. 提取重叠判断为工具方法
把日期重叠的逻辑提取到Booking类中,让代码更清晰、可复用:
// 在Booking类中添加方法 public boolean overlapsWith(LocalDate otherCheckin, LocalDate otherCheckout) { return otherCheckin.isBefore(this.getCheckout()) && otherCheckout.isAfter(this.getCheckin()); }
然后isAvailableBetween可以简化成:
public boolean isAvailableBetween(LocalDate newCheckin, LocalDate newCheckout) { if (newCheckin.isAfter(newCheckout) || newCheckin.isEqual(newCheckout)) { return false; } return this.bookings.stream() .noneMatch(booking -> booking.overlapsWith(newCheckin, newCheckout)); }
2. 优化并发场景下的竞态问题
当前的检查+添加操作不是原子性的,如果有多个请求同时检查同一个住宿的可用性,可能会出现“同时通过检查,然后都添加了重叠预订”的情况。解决方法:
- 在Service层的添加预订方法上加上事务,并使用数据库乐观锁(比如给
Accommodation加一个version字段,更新时校验版本号) - 或者用数据库的唯一约束/范围约束(部分数据库支持,比如PostgreSQL的
EXCLUDE约束),从底层防止重叠预订
3. 性能优化(针对大量预订场景)
如果某个住宿的预订数量特别多,遍历所有预订会影响性能:
- 可以把
bookings列表按checkin日期排序,然后用二分查找快速定位可能和新预订重叠的预订范围,减少遍历次数 - 比如:找到第一个
checkout > newCheckin的预订,然后从这个位置开始遍历到最后一个checkin < newCheckout的预订,中间的才是需要检查的对象
4. 提前校验DTO合法性
在BookingDto接收前端请求时,就先校验checkin和checkout的合法性(比如用Spring的@Valid注解+自定义校验器),避免无效请求到达Service层,减少不必要的处理。
内容的提问来源于stack exchange,提问作者Andrea Damiani
相关产品推荐
相关产品推荐

