为了账号安全,请及时绑定邮箱和手机立即绑定

HashMap 忽略重写的 hashCode 和 equals 方法

HashMap 忽略重写的 hashCode 和 equals 方法

慕虎7371278 2023-10-13 17:21:24
我正在从文件加载网络流量数据。我正在加载的信息是攻击者 IP 地址、受害者 IP 地址和日期。我已将这些数据组合成一个Traffic对象,并为其定义了hashCode和equals函数。尽管如此,HashMap我将它们加载到将相同的Traffic对象视为不同的键。整个 Traffic 对象在方法中包含一些简单的测试代码,main如下所示:import java.util.HashMap;public class Traffic {    public String attacker;    public String victim;    public int date;    //constructors, getters and setters    @Override    public int hashCode() {        long attackerHash = 1;        for (char c:attacker.toCharArray()) {            attackerHash = attackerHash * Character.getNumericValue(c) + 17;        }        long victimHash = 1;        for (char c:victim.toCharArray()) {            victimHash = victimHash * Character.getNumericValue(c) + 17;        }        int IPHash = (int)(attackerHash*victimHash % Integer.MAX_VALUE);        return (IPHash + 7)*(date + 37) + 17;    }    public boolean equals(Traffic t) {        return this.attacker.equals(t.getAttacker()) && this.victim.equals(t.getVictim()) && this.date == t.getDate();    }    public static void main(String[] args) {        Traffic a = new Traffic("209.167.099.071", "172.016.112.100", 7);        Traffic b = new Traffic("209.167.099.071", "172.016.112.100", 7);        System.out.println(a.hashCode());        System.out.println(b.hashCode());        HashMap<Traffic, Integer> h = new HashMap<Traffic, Integer>();        h.put(a, new Integer(1));        h.put(b, new Integer(2));        System.out.println(h);    }}我无法说出我的哈希方法的强度,但前两个打印的输出是相同的,这意味着它至少适用于这种情况。由于 a 和 b 的数据相同(因此equals返回 true),并且哈希值相同,因此HashMap应该将它们识别为相同并将值从 1 更新为 2,而不是创建值为 2 的第二个条目。不幸的是,它确实如此无法将它们识别为相同,最终打印的输出如下:{packagename.Traffic@1c051=1, packagename.Traffic@1c051=2}我对此的最佳猜测是,HashMap内部运作忽略了我的习惯hashCode和equals方法,但如果是这样的话,那为什么呢?如果这个猜测是错误的,那么这里发生了什么?
查看完整描述

1 回答

?
函数式编程

TA贡献1807条经验 获得超9个赞

这里的问题是你的equals方法,它没有覆盖Object#equals. 为了证明这一点,下面的注释将无法编译@Override:


@Override

public boolean equals(Traffic t) {

    return this.attacker.equals(t.getAttacker()) && 

        this.victim.equals(t.getVictim()) && 

        this.date == t.getDate();

}

HashMap使用的实现Object#equals而不是您的自定义实现。您的equals方法应该接受 anObject作为参数:


@Override

public boolean equals(Object o) {

    if (!(o instanceof Traffic)) {

        return false;

    }


    Traffic t = (Traffic) o;


    return Objects.equals(attacker, t.attacker) &&

        Objects.equals(victim, t.victim) &&

        date == t.date;

}


查看完整回答
反对 回复 2023-10-13
  • 1 回答
  • 0 关注
  • 109 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信