Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的HashMap允许重复键?_Java_Hashmap - Fatal编程技术网

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

Java 为什么我的HashMap允许重复键?,java,hashmap,Java,Hashmap,嘿,我正在使用一个HashMap来跟踪公告栏上的服务和服务请求。但是,我必须把hashcode和equals搞错,因为我得到了重复的密钥。谁能告诉我为什么会这样 键集的内容: 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<>(); ..

嘿,我正在使用一个
HashMap
来跟踪公告栏上的服务和服务请求。但是,我必须把hashcode和equals搞错,因为我得到了重复的密钥。谁能告诉我为什么会这样

键集的内容:

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;
}
}
private static final HashMap services=new HashMap();
...
公共类广告{
私有int-id;
私人董事会海报;
公共广告(海报){
this.poster=海报;
}
公众海报{
返回海报;
}
公共void spawn(){
id=随机.nextInt(广告范围);
}
公共int getID(){
返回id;
}
@凌驾
公共字符串toString(){
返回整数.toString(id);
}
@凌驾
公共布尔等于(对象o){
如果(o!=null&&o广告实例){
return((广告)o).id==id;
}
返回false;
}
@凌驾
公共int hashCode(){
返回67*5+this.id;
}
}

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

map.put(anAdvert, 1);
anAdvert.spawn(); //modifies id, which affects hashcode and equals
地图的行为将是意外的

碳纤维

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


一句话:检查
o!=广告
的null和o实例是多余的<如果
o
null
,则code>o广告实例返回
false
。在Java中,
null
不被视为任何类型,因此对它的所有实例检查都会失败@assylias这是一种不好的hashcode方法,因为它实际上不是散列。返回
this.id%1000
可能是更好的选择。@ErickRobertson它将用作映射的键:为什么要将可能的值数限制为1000,从而显著增加哈希冲突的可能性?一般来说,您希望hashcode为不同的对象生成不同的值,并且在任何情况下都要使用整数值的整个范围。对于这样的属性,最好使用
final
关键字。切勿将可变对象用作映射键!