我正在从文件加载网络流量数据。我正在加载的信息是攻击者 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方法,但如果是这样的话,那为什么呢?如果这个猜测是错误的,那么这里发生了什么?
函数式编程
相关分类