首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >HashSet允许多个项目具有相同的HashCode

HashSet允许多个项目具有相同的HashCode
EN

Stack Overflow用户
提问于 2019-06-04 01:41:57
回答 2查看 347关注 0票数 0

我的HashSet包含多个具有相同HashCode的'AccessRequests‘。我只希望有一个实例。我不认为具有相同HashCode的项目可以在HashSet中显示。我在这里做错了什么?

更新:基于假设HashSet只保留列表中不等于另一项的项,并且可能我的equals/hash方法需要简化,我已经更新了我的问题。在我的HashSet中,我仍然会得到多个评估为等于的项目。

下面是来自'AccessRequest‘的HashCode和Equals方法

更新:我更新了我的hash和equals,只包含我需要“相等”的必要字段。

    @Override
public int hashCode() {
    int hash = 5;
    hash = 79 * hash + Objects.hashCode(this.targets);
    hash = 79 * hash + Objects.hashCode(this.sources);
    hash = 79 * hash + Objects.hashCode(this.destinations);
    hash = 79 * hash + Objects.hashCode(this.services);
    hash = 79 * hash + Objects.hashCode(this.action);
    return hash;
}

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final AccessRequest other = (AccessRequest) obj;
    if (!Objects.equals(this.action, other.action)) {
        return false;
    }
    if (!Objects.equals(this.targets, other.targets)) {
        return false;
    }
    if (!Objects.equals(this.sources, other.sources)) {
        return false;
    }
    if (!Objects.equals(this.destinations, other.destinations)) {
        return false;
    }
    if (!Objects.equals(this.services, other.services)) {
        return false;
    }
    return true;
}

在创建AccessRequests之后,我将它们转储到一个HashSet中并迭代:我的HashSet定义如下:

 Set<AccessRequest> ars = new HashSet();

       ArrayList<AccessRequest> arsAsList = new ArrayList(ars);
        for(int position=0;position<arsAsList.size();position++){
            AccessRequest fixedAR = arsAsList.get(position);
            ArrayList<AccessRequest> comparToList = new ArrayList(ars);
            for(int cPosition=0;cPosition<comparToList.size();cPosition++){
                AccessRequest nextAR = comparToList.get(cPosition);
                if(fixedAR.equals(nextAR)){
                    System.out.println("position= "+position+"  cPosition "+cPosition);
                }
            }
            System.out.println("\n Next AR");
        }

以下是输出:

position= 0  cPosition 0
position= 0  cPosition 5
position= 0  cPosition 6
position= 0  cPosition 14
position= 0  cPosition 24
position= 0  cPosition 32
position= 0  cPosition 39
position= 0  cPosition 40
position= 0  cPosition 43
position= 0  cPosition 77
position= 0  cPosition 96
position= 0  cPosition 97
position= 0  cPosition 99
position= 0  cPosition 109
position= 0  cPosition 111
position= 0  cPosition 115
position= 0  cPosition 173
position= 0  cPosition 182
position= 0  cPosition 187
EN

回答 2

Stack Overflow用户

发布于 2019-06-04 01:47:48

基于equals方法(1)设置防止重复。来自javadoc (我强调):

不包含重复元素的集合。

如果根据散列代码,您的元素应该相等,则相应地实现equals方法(例如,只比较调用hashCode的结果)。请注意,这可能不是最好的想法,因为您的equals方法当前计算更多的属性。

(1):至少是您当前使用的HashSet

票数 4
EN

Stack Overflow用户

发布于 2019-06-04 02:11:00

由于散列代码函数将值从较大的集合(例如,所有可能的String,它们的数量是无限的)映射到较小的集合(例如,所有可能的int,只有2^32个不同的值),因此总是会有冲突。

您可以查看Hash Tables wiki, Collision resolution section以更好地了解问题:

例如,如果2450个密钥被散列到一百万个桶中,即使具有完全均匀的随机分布,根据生日问题,至少有两个密钥被散列到同一个槽的可能性大约为95%。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56432164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档