
本文介绍如何实现一个健壮的 mostFrequentDayOfWeek 方法:在统计日期数组中各星期几出现频次时,当多个星期几频次相同时,严格按“Mon→Tue→Wed→Thu→Fri→Sat→Sun”自然周序返回索引最小(即最早)的那个,而非任意或字典序结果。
本文介绍如何实现一个健壮的 `mostfrequentdayofweek` 方法:在统计日期数组中各星期几出现频次时,当多个星期几频次相同时,严格按“mon→tue→wed→thu→fri→sat→sun”自然周序返回**索引最小(即最早)的那个**,而非任意或字典序结果。
在处理日期分析类任务时,仅统计频次往往不够——业务逻辑常要求确定性行为,尤其在存在并列(tie)的情况下。例如,题目要求:若 "Tue" 和 "Fri" 同为最高频(如各出现 3 次),应返回 "Tue",因其在标准周序列 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" 中位置更靠前(索引更小)。原始代码中使用 Vector 动态收集候选值但未建立可比较的顺序基准,导致无法判断“谁更早”。
核心解法在于显式定义星期几的有序参考序列,并将其作为比较依据。推荐使用 List<String> 预置标准顺序,再通过 indexOf() 快速获取每个星期几的规范序号:
public static String mostFrequentDayOfWeek(SimpleDate[] dates) {
if (dates == null || dates.length == 0) {
throw new IllegalArgumentException("Dates array must not be null or empty");
}
// 定义标准周序:Mon → Sun 对应索引 0 → 6(注意:此处按题目要求以 Mon 为起点)
// ⚠️ 注意:原答案使用 "Sun" 开头,但题干明确要求 "from 'Mon' to 'Sun'",
// 因此我们严格采用 ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]
List<String> weekOrder = Arrays.asList("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
int maxCount = 0;
int minIndex = Integer.MAX_VALUE; // 记录当前最优星期几在 weekOrder 中的索引
String freqDay = "";
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 || (count == maxCount && currentIndex < minIndex)) {
maxCount = count;
minIndex = currentIndex;
freqDay = day1;
}
}
return freqDay;
}✅ 关键改进点说明:
- 明确周序定义:使用 Arrays.asList("Mon", "Tue", ..., "Sun") 建立唯一、可索引的顺序基准;
- 统一比较维度:用 weekOrder.indexOf(day) 将字符串映射为整数序号("Mon"→0, "Sun"→6),使“最早”可量化、可比较;
- 原子化更新逻辑:单次 if 判断同时覆盖“频次提升”与“频次持平但序号更优”两种场景,避免状态不一致;
- 健壮性增强:添加空输入校验,防止 NullPointerException。
⚠️ 注意事项:
- dayOfWeek() 方法返回值必须严格匹配列表中的字符串(大小写、缩写格式一致),否则 indexOf() 返回 -1,导致逻辑错误;
- 原始代码中 else if 块内重复创建 Vector 并错误调用 days.get(i) 是典型逻辑缺陷——i 是外层循环索引,与 days 大小无关,极易引发 IndexOutOfBoundsException;
- 时间复杂度为 O(n²),适用于中小规模数据;如需高性能(如海量日期),建议改用 HashMap<String, Integer> 先统计频次,再遍历 weekOrder 找首个最大频次项(O(n))。
综上,解决“频次相同时取最早星期几”的本质,是将模糊的语义约束(“最早”)转化为精确的程序化指标(预定义顺序中的最小索引)。这一模式可泛化至任何需要“主键优先、次键保序”的多条件选择问题。










