HashSet <pojo> .contains行为不端

时间:2018-03-19 11:52:51

标签: java hadoop hashset mapper

作为Hadoop .mat-select-content, .mat-select-panel-done-animating { background: mat-color($background, card); .mat-option { color : mat-color($foreground, text); } } 的一部分,我有一个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()仅用于比较给定存储桶中的实例。
我尝试更改equals()中的素数值以将实例不同地分散到桶中,并且看到hasCode()有时仍会返回错误的结果,但不会返回相同的先前失败的值。
似乎这个值被正确识别为超出集合;因此我怀疑平等检查而不是散列有问题,但我可能错了......

我在这里完全失去了想法。任何人都可以对此有所了解吗?

-----编辑-----
一些澄清:

  • contains()&amp;在构造之后,i1永远不会更新为添加到集合中的实例(尽管它们有时会更新,代码中的其他位置,对于同一个类的其他实例);
  • 该集合可能非常大(即可以达到近15K条目),我想知道问题是否可以与此相关联(存储桶溢出,例如?)。

1 个答案:

答案 0 :(得分:0)

我敢打赌,你很难想出这个错误的简洁再现。

您显示的代码看起来正确。我认为你的集合中的对象正在发生变异,而其他代码也会掩盖这一事实。

你可以通过临时添加:

来调试它
  1. boolean hashCodeCalled=false添加到您的班级
  2. 调用hashCode()时,设置hashCodeCalled=true
  3. 调用setter时,boolean为true,然后抛出异常或记录当前堆栈跟踪
  4. 或者,你可以重构你的代码,使这些实例是不可变的,我打赌问题就会消失。