为什么我的HashMap允许重复键?

嘿,我正在使用HashMap来跟踪BulletinBoard上的服务和服务请求。 但是,我必须有哈希码并且等于错误,因为我得到了重复的密钥。 任何人都可以告诉为什么这可能是?

keySet的内容:

 Services: [1, 1, 6, 6, 3] Requests: [8, 7, 6, 5, 8, 4, 5, 6, 2] 

这是相关的代码:

 private static final HashMap services = new HashMap(); ... public class Advert { private int id; private BoardPoster poster; public Advert(BoardPoster poster) { this.poster = poster; } public BoardPoster getPoster() { return poster; } public void spawn() { id = RANDOM.nextInt(ADVERT_RANGE); } public int getID() { return id; } @Override public String toString() { return Integer.toString(id); } @Override public boolean equals(Object o) { if (o != null && o instanceof Advert) { return ((Advert) o).id == id; } return false; } @Override public int hashCode() { return 67 * 5 + this.id; } } 

最有可能的原因是你用作键的对象是可变的。 所以如果你做的事情如下:

 map.put(anAdvert, 1); anAdvert.spawn(); //modifies id, which affects hashcode and equals 

地图的行为将是意外的。

cf Map的javadoc

注意:如果将可变对象用作映射键,则必须非常小心。 如果在对象是地图中的键的同时以影响等于比较的方式更改对象的值,则不指定映射的行为。