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

时间:2012-09-14 14:39:35

标签: java hashmap

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

keySet的内容:

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

以下是相关代码:

private static final HashMap<Advert, Integer> 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;
}
}

1 个答案:

答案 0 :(得分:18)

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

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

地图的行为会出乎意料。

cf Map's javadoc

  

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