JAVA实现计算最大连续天数 比如连续签到天数 连续参加抽奖天数
/**
* 计算最大连续天数
*
* @param days
* @return
*/
private Integer calcContinuousDay(List<String> days) {
if (days == null || days.size() == 0) {
return 0;
}
List<LocalDate> localDates = days.stream().map(day -> LocalDate.of(Integer.parseInt(day.substring(0, 4)), Integer.parseInt(day.substring(4, 6)), Integer.parseInt(day.substring(6)))).collect(Collectors.toList());
int continuousDay = 1, maxContinuousDay = 1;
for (int i = 0; i < localDates.size() - 1; i++) {
if (localDates.get(i).plusDays(1).equals(localDates.get(i + 1))) {
continuousDay++;
} else {
maxContinuousDay = Math.max(continuousDay, maxContinuousDay);
continuousDay = 1;
}
}
return Math.max(continuousDay, maxContinuousDay);
}
另一种解法
/**
* 计算最大连续天数 哈希表法
*
* @param days
* @return
*/
private Integer calcContinuousDay2(List<String> days) {
if (days == null || days.size() == 0) {
return 0;
}
Set<LocalDate> localDates = days.stream().map(day -> LocalDate.of(Integer.parseInt(day.substring(0, 4)), Integer.parseInt(day.substring(4, 6)), Integer.parseInt(day.substring(6)))).collect(Collectors.toSet());
int longestStreak = 0;
for (LocalDate date : localDates) {
if (!localDates.contains(date.minusDays(1))) {
int currentStreak = 1;
LocalDate currentDate = date;
while (localDates.contains(currentDate = currentDate.plusDays(1))) {
currentStreak++;
}
longestStreak = Math.max(longestStreak, currentStreak);
}
}
return longestStreak;
}
测试代码
@Test
public void testContinuousDay() {
List<String> days = Arrays.asList("20230914", "20230915", "20230916", "20230918", "20230919", "20230920", "20230921");
System.out.println(calcContinuousDay(days));
}
必须先对日期进行排序 举例mysql直接查询参与的天
<select id="queryLotteryDays" resultType="string">
select date_format(create_time,'%Y%m%d') `day` from ${tableName} where ... group by `day` order by `day`
</select>