hashset< pojo>包含错误行为

kmb7vmvb  于 2021-06-01  发布在  Hadoop
关注(0)|答案(1)|浏览(356)

作为hadoop的一部分 Mapper ,我有一个 HashSet<MySimpleObject> 它包含只有两个整数属性的非常简单的类的示例。作为一个应该,我定制 hashCode() 以及 equals() :

public class MySimpleObject {

  private int i1, i2;

  public set(int i1, int i2) {
    this.i1 = i1;
    this.i2 = i2;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + i1;
    result = prime * result + i2;
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == null) return false;
    if (this == obj) return true;
    if ( obj.getClass() != MySimpleObject.class ) return false;

    MySimpleObject other = (MySimpleObject)obj;
    return (this.i1 == other.i1) && (this.i2 == other.i2);
  }

不知何故,有时 mySet.contains(aSimpleObj) 返回 true 尽管集合实际上不包含这个值。
我知道怎么做 hashCode() 首先用于将示例拆分为bucket和 equals() 仅为比较给定bucket中的示例而调用。
我试着改变 hasCode() 将不同的示例分散到桶中,并看到 contains() 有时仍然返回错误的结果,但不是以前失败的值。
似乎这个值也被正确地识别为超出了集合;因此,我怀疑是平等检查而不是哈希错误,但我可能是错的。。。
我在这里完全不知所措,没有主意了。有人能解释一下吗?
-----编辑-----
一些澄清: i1 & i2 对于已添加到集合中的示例,在构造之后从不更新(尽管有时在代码的其他地方,对于同一类的其他示例,它们也会更新);
集合可能相当大(即可以达到近15k个条目),我想知道问题是否与此有关(bucket overflow,例如?)。

vawmfj5a

vawmfj5a1#

我敢打赌你很难想出一个简洁的复制这个错误。
显示的代码看起来正确。我认为您的集合中的对象正在发生变化,这一事实被其他代码掩盖了。
可以通过临时添加以下内容对此进行调试:
添加 boolean hashCodeCalled=false 为你们班干杯
调用hashcode()时,设置 hashCodeCalled=true 当调用setter时,该布尔值 true ,然后抛出异常或记录当前堆栈跟踪
或者,您可以重构代码,使这些示例是不可变的,我敢打赌问题消失了。

相关问题