
本文介绍如何实现一个健壮的 mostFrequentDayOfWeek 方法:在统计日期数组中各星期几出现频次后,当存在多个最高频次的星期几时,优先返回按自然周序("Sun"→"Mon"→…→"Sat")最靠前的那个。
本文介绍如何实现一个健壮的 `mostfrequentdayofweek` 方法:在统计日期数组中各星期几出现频次后,当存在多个最高频次的星期几时,优先返回按自然周序("sun"→"mon"→…→"sat")最靠前的那个。
在处理日期频次统计类问题时,仅关注“最大频次”是不够的——业务逻辑常要求确定性破歧义:当多个星期几并列最高频次时,必须有明确、可复现的选取规则。本例要求选择“最早”的一天,即按标准周序 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 中索引最小者。
核心思路是:将星期几映射为有序索引,比较频次相同时的索引大小,而非字符串字典序。原代码中使用 Vector<String> 临时存储并错误调用 days.get(i),不仅逻辑混乱,且未建立星期几与顺序的显式关联,导致无法判断“谁更早”。
以下是优化后的完整实现:
import java.util.Arrays;
import java.util.List;
public static String mostFrequentDayOfWeek(SimpleDate[] dates) {
if (dates == null || dates.length == 0) {
throw new IllegalArgumentException("Dates array cannot be null or empty");
}
// 定义标准周序(从 Sunday 开始,符合 Zeller 公式余数约定)
List<String> weekOrder = Arrays.asList("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
int maxCount = 0;
int minIndex = Integer.MAX_VALUE; // 记录当前最优星期几在 weekOrder 中的索引
String freqDay = "Sun"; // 默认值,确保非空
for (SimpleDate d1 : dates) {
String day1 = dayOfWeek(d1);
int count = 0;
// 统计 day1 在整个数组中出现次数
for (SimpleDate d2 : dates) {
if (day1.equals(dayOfWeek(d2))) {
count++;
}
}
int currentIndex = weekOrder.indexOf(day1);
// 频次更高 → 直接更新
if (count > maxCount) {
maxCount = count;
minIndex = currentIndex;
freqDay = day1;
}
// 频次相同 → 比较周序索引,取更小(即更早)者
else if (count == maxCount && currentIndex < minIndex) {
minIndex = currentIndex;
freqDay = day1;
}
}
return freqDay;
}✅ 关键改进说明:
- 使用 Arrays.asList(...) 构建不可变但语义清晰的周序列表,避免 Vector 的冗余与线程安全开销;
- 引入 minIndex 变量追踪当前最优星期几的位置序号,而非依赖字符串比较(如 "Fri".compareTo("Mon") 会返回负数,但“Fri”实际晚于“Mon”);
- 显式处理边界情况:空/无效输入抛出异常,提升鲁棒性;
- 内层循环逻辑简洁,无重复计算或变量遮蔽(原代码中重复声明 Vector<String> days 导致编译错误风险)。
⚠️ 注意事项:
- dayOfWeek() 方法返回值必须严格限定为上述 7 个缩写之一(大小写敏感),否则 weekOrder.indexOf() 将返回 -1,引发逻辑错误;
- 该算法时间复杂度为 O(n²),适用于中小规模数据;若需高性能(如海量日期),建议改用 HashMap<String, Integer> 先统频次,再遍历 weekOrder 查找首个最大值,可优化至 O(n);
- 周序定义需与 dayOfWeek() 的返回逻辑一致(本例中 Zeller 公式余数 0→"Sat"?但答案中为 0→"Sat" 而代码设为 "Sun",实际应以 dayOfWeek() 实现为准——本文采用答案提供的 {"Sun","Mon",...,"Sat"} 顺序,因其与常见日历 UI 习惯一致)。
通过将“语义顺序”显式建模为索引,我们使破歧义逻辑变得直观、可验证且易于维护——这正是专业级日期工具方法应有的设计水准。

















