热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何确保hashcode()在Java中不能解析为相同的值?

如何解决《如何确保hashcode()在Java中不能解析为相同的值?》经验,为你挑选了1个好方法。

我有一个类的哈希码实现,哈希码实现与eclipse生成的一致,也是这里讨论的最常被接受的实践

这是我的哈希码实现(此方法中使用的所有ID都构成了对象的键):

public int hashCode() {
    final int prime = 31;
    int hashCode = 1;
    if(uId != null){
        hashCode = prime * hashCode + uId.hashCode();
    }
    if(rId != null){
        hashCode = prime * hashCode + rId.hashCode();
    }
    if(bId != null){
        hashCode = prime * hashCode + bId.hashCode();
    }
    if(reId != null){
        hashCode = prime * hashCode + reId.hashCode();
    }
    if(cId != null){
        hashCode = prime * hashCode + cId.hashCode();
    }
    return hashCode;
}

我遇到了一个使用非常大的数据集进行测试的场景,而且我的集合没有这个类的预期数量的对象.仔细观察下面两个数据集导致相同的哈希码:50268236873,因此一条记录被添加到集合中的最后一个替换,因为它们的哈希码是相同的.

  Existing record :
  Record@2c0781cd[uId=54046,rId=10967,bId=177,reId=1728,cId=50194] 

  Record being inserted into the collection :
  Record@20dad050[uId=53806,rId=18389,bId=177,reId=19026,cId=50194]

Both of these had the hashCode value = 50268236873 

所以,问题:

1]这是两个不同对象的哈希码具有相同值的明显情况.那么如何确保任何数据集都不会发生这种情况?素数应该更大吗?

2]如果仔细观察,实现中的hashCode变量是int数据类型,其最大值是2 ^ 31-1 = 2147483647,这大于为上述数据集计算的哈希码= 50268236873,所以有溢出.使用long作为hashCode值的类型有什么后果吗?

谢谢
Nohsib

编辑:

我正在使用HashSet,在阅读了发布的答案后,我查找了equals实现,如下所示,我认为因为在等于我检查两个对象的hashCodes是否相同并使用它来确定它们是否相同相同的对象导致了这个问题.

你们中的任何人都可以证实吗?

@Override
    public boolean equals(Object paramObject) {
        boolean equals = false;
        if (paramObject != null) {
            ACRecord other = (ACRecord) paramObject;
            if ((this.hashCode() == other.hashCode()) // I think this is where I am going wrong
                    || (this.uId.equals(other.getUId())
                            && this.rId.equals(other.getRId())
                            && this.reId.equals(other.getReId())
                            && this.bId.equals(other.getBId()) 
                            && this.cId.equals(other.getCId))) {
                equals = true;
            }
        }
        return equals;
    }

解决方案:我的equals方法实现错误,因为我使用hashCode来确定两个对象是否相等.修正了equals方法实现解决了我的问题,hashset正在替换exisintg记录.



1> L. Blanc..:

通常,哈希码不保证唯一性.HashMap实现通常通过在幕后存储列表来处理冲突,但它们包括一个检查,确保您不会将列表中的所有内容都作为匹配项,只是那些真正匹配的项.

换句话说,如果你执行map.get("foo")并且存在冲突,则哈希映射将检查每个结果(未哈希)以查看它是否真正匹配"foo".然后它只返回完全匹配.

还要注意,虽然哈希码的契约声明任何两个对equals()响应为true的对象应该具有相同的哈希码,但相反的情况不一定如此.


@Nohsib - 你误解了哈希码的契约 - 它提供了哈希,而不是唯一的ID.如果您正在使用使用哈希码的Java集合,那么只要您正确地实现了等号,它们就可以解决如何在没有重复和冲突的情况下存储事物.您的代码的真正问题不是哈希码的实现,而是您构建集合的方式 - 您是否愿意共享它?
推荐阅读
author-avatar
PHP小龙
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有