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

标签 java hashset

我的 HashSet 包含多个具有相同 HashCode 的“AccessRequest”。我只希望有一个实例。我不认为具有相同 HashCode 的项目可以出现在 HashSet 中。我在这里做错了什么?

更新:基于 HashSet 只保留列表中不等于另一个项的假设,并且也许我的 equals/hash 方法需要简化,我更新了我的问题。我仍然收到多个在我的哈希集中计算结果等于的项目。

以下是“AccessRequest”中的 HashCode 和 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;
}

创建 AccessRequest 后,我​​将它们转储到 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

最佳答案

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

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element.

如果您的元素根据其哈希码应该相等,则相应地实现 equals 方法(例如,仅比较调用 hashCode 的结果)。请注意,这可能不是最好的主意,因为您的 equals 方法当前评估更多属性。

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

关于java - HashSet允许多个项目具有相同的HashCode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56432164/

相关文章:

java - JDBC : foreign key on PK created in same transaction

java - Replaceall 方法未按预期工作。文字被替换两次

java - 元素返回空字符串

java - 在 Java 中迭代 HashSet 的最佳方法

java - 从对象获取信息(JAVA)

java - 如何在调用 HashSet.add() 时使 HashSet<T> 调用 T.equals(Object )

java - SharedArray 死锁和引发条件

java - Java HashSet<String> 的 contains() 方法会测试字符串或对象标识的相等性吗?

c# - 过滤列表中的重复项

java - 页面中外部资源的 GIF 在 apache wicket Web 应用程序中没有动画