You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java使用HashMap统计每日疾病确诊数计数重复问题如何修复

问题根因

HashMap判断两个key是否为同一个的逻辑为:先校验两个对象的hashCode()返回值是否相等,若相等再调用equals()方法判断是否返回true,两者同时满足才会判定为同一key。
当前你使用Diagnosis类作为HashMap的key,但Diagnosis类没有重写hashCode()和equals()方法,采用的是Object类的默认实现:默认hashCode()返回对象内存地址映射值,equals()直接对比对象内存地址。因此即使两个Diagnosis实例的disease和day属性完全一致,只要是不同的实例对象,就会被HashMap判定为不同key,无法正确累加计数。
由于你明确要求不能修改Diagnosis和Disease类,因此需要调整HashMap的key规则来解决该问题。

修复方案

我们可以构造一个自定义组合键作为HashMap的key,组合键包含疾病和日期两个属性,且正确实现hashCode()和equals()逻辑即可。这里推荐使用JDK自带的AbstractMap.SimpleEntry作为组合键(该类已经内置了正确的equals和hashCode实现),同时注意修正原main方法中调用printFreq时的参数拼写错误。

修改后的完整代码

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DiagnosisStats {
    public static void main(String[] args) {
        Disease cholera = new Disease("cholera");
        Disease dengue = new Disease("dengue");

        List<Diagnosis> diagnoses = Arrays.asList(
                new Diagnosis(cholera, 0),
                new Diagnosis(cholera, 0),
                new Diagnosis(cholera, 1),
                new Diagnosis(cholera, 1),
                new Diagnosis(cholera, 2),
                new Diagnosis(cholera, 2),
                new Diagnosis(dengue, 0)
        );
        // 修正原参数拼写错误
        printFreq(diagnoses);
    }

    public static void printFreq(List<Diagnosis> diagnoses) {
        Map<AbstractMap.SimpleEntry<Disease, Integer>, Integer> hm = new HashMap<>();
        for (Diagnosis x : diagnoses) {
            AbstractMap.SimpleEntry<Disease, Integer> key = new AbstractMap.SimpleEntry<>(x.getDisease(), x.getDay());
            // 简化计数逻辑,无需判断key是否存在
            hm.put(key, hm.getOrDefault(key, 0) + 1);
        }
        // 按你需要的格式输出结果
        for (Map.Entry<AbstractMap.SimpleEntry<Disease, Integer>, Integer> entry : hm.entrySet()) {
            System.out.printf("{%s, %d}=%d ", entry.getKey().getKey(), entry.getKey().getValue(), entry.getValue());
        }
    }
}

如果你使用的JDK版本不支持getOrDefault方法,也可以替换为原有判断逻辑:

if (!hm.containsKey(key)) {
    hm.put(key, 1);
} else {
    hm.put(key, hm.get(key) + 1);
}

可选替代方案

如果不想依赖AbstractMap.SimpleEntry,也可以在当前业务类中自定义一个静态内部类作为组合键:

private static class DiagnosisKey {
    private final Disease disease;
    private final int day;

    public DiagnosisKey(Disease disease, int day) {
        this.disease = disease;
        this.day = day;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DiagnosisKey that = (DiagnosisKey) o;
        return day == that.day && disease.equals(that.disease);
    }

    @Override
    public int hashCode() {
        int result = disease.hashCode();
        result = 31 * result + day;
        return result;
    }
}

使用时将HashMap的key替换为DiagnosisKey即可,逻辑和上述实现完全一致。

内容的提问来源于stack exchange,提问作者StephenHawkingi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:15:04